/*------------------------------------------------------------\
|                                                             |
| Tool    :                     RDS                           |
|                                                             |
| File    :                  Rfmacces.c                       |
|                                                             |
| Authors :                Jacomme Ludovic                    |
|                                                             |
| Date    :                   01.08.93                        |
|                                                             |
\------------------------------------------------------------*/

/*------------------------------------------------------------\
|                                                             |
|                         Include Files                       |
|                                                             |
\------------------------------------------------------------*/

# include MUT_H
# include MPH_H
# include RDS_H
# include RPR_H
# include RFM_H
# include RUT_H

# include "rfmacces.h"
# include "rfmerror.h"

/*------------------------------------------------------------\
|                                                             |
|                           Constants                         |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                            Types                            |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                          Variables                          |
|                                                             |
\------------------------------------------------------------*/

  static char *RfmRefRef = (char *)NULL;

  static char  RfmNewConnectorOrient[ RDS_MAX_TRANSF ] =

     {
       1,  /* NOSYM */
       0,  /* ROT_P */
       1,  /* SYMXY */
       0,  /* ROT_M */
       1,  /* SYM_X */
       0,  /* SY_RM */
       1,  /* SYM_Y */
       0   /* SY_RP */
     };

/*------------------------------------------------------------\
|                                                             |
|                          Functions                          |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                MBK Segment To RDS Rectangle                 |
|                                                             |
\------------------------------------------------------------*/

  rdsrec_list *segmbkrds( Figure, Segment, Lynx )

     rdsfig_list *Figure;
     phseg_list  *Segment;
     char         Lynx;
  {
    rdsrec_list  *Rectangle;
    rdsrec_list  *First;
    rdsrec_list  *Link;

    long          X1;
    long          Y1;
    long          X2;
    long          Y2;
    long          WS;

    long          X1R;
    long          Y1R;
    long          X2R;
    long          Y2R;

    char          TRANS;
    long          DLR;
    long          DWR;
    long          OFFSET;
    char          USE; 

    char          LayerMbk;
    char          LayerRds;
    char          Index;

    Rectangle = (rdsrec_list *)NULL;
    First     = (rdsrec_list *)NULL;
    Link      = (rdsrec_list *)NULL;

    X1 = Segment->X1    * RDS_LAMBDA / SCALE_X;
    X2 = Segment->X2    * RDS_LAMBDA / SCALE_X;
    Y1 = Segment->Y1    * RDS_LAMBDA / SCALE_X;
    Y2 = Segment->Y2    * RDS_LAMBDA / SCALE_X;
    WS = Segment->WIDTH * RDS_LAMBDA / SCALE_X;

    LayerMbk  = Segment->LAYER;
    Index     = 0;

    LayerRds  = GET_SEGMENT_LAYER( LayerMbk, Index );

    while ( LayerRds != RDS_SEGMENT_EMPTY )
    {
      TRANS  = GET_SEGMENT_TRANS ( LayerMbk, Index );
      DLR    = GET_SEGMENT_DLR   ( LayerMbk, Index );
      DWR    = GET_SEGMENT_DWR   ( LayerMbk, Index );
      OFFSET = GET_SEGMENT_OFFSET( LayerMbk, Index );
      USE    = GET_SEGMENT_USE   ( LayerMbk, Index );

      if ( ( ( USE == RDS_USE_ALL     )               ) ||
           ( ( USE == RDS_USE_EXTRACT ) && (   Lynx ) ) ||
           ( ( USE == RDS_USE_DRC     ) && ( ! Lynx ) ) )
      {
        if ( TRANS == RDS_TRANS_VW )
        {
          switch ( Segment->TYPE )
          {
            case LEFT   : X1R = X1 - DLR;
                          Y1R = Y1 - ( ( WS + DWR ) >> 1 ) + OFFSET;
                          X2R = X2 + DLR;
                          Y2R = Y2 + ( ( WS + DWR ) >> 1 ) + OFFSET;

                        break;

            case RIGHT  : X1R = X1 - DLR;
                          Y1R = Y1 - ( ( WS + DWR ) >> 1 ) - OFFSET;
                          X2R = X2 + DLR;
                          Y2R = Y2 + ( ( WS + DWR ) >> 1 ) - OFFSET;

                        break;

            case DOWN   : X1R = X1 - ( ( WS + DWR ) >> 1 ) - OFFSET;
                          Y1R = Y1 - DLR;
                          X2R = X2 + ( ( WS + DWR ) >> 1 ) - OFFSET;
                          Y2R = Y2 + DLR;

                        break;

            case UP     : X1R = X1 - ( ( WS + DWR ) >> 1 ) + OFFSET;
                          Y1R = Y1 - DLR;
                          X2R = X2 + ( ( WS + DWR ) >> 1 ) + OFFSET;
                          Y2R = Y2 + DLR;

                        break;
          }
        }
        else
        if ( TRANS == RDS_TRANS_LCW )
        {
          switch ( Segment->TYPE )
          {
            case RIGHT  : X1R = X1 - DLR;
                          Y1R = Y1 + (WS >> 1) + OFFSET;
                          X2R = X2 + DLR;
                          Y2R = Y2 + (WS >> 1) + DWR + OFFSET;

                        break;

            case LEFT   : X1R = X1 - DLR;
                          Y1R = Y1 - (WS >> 1) - DWR - OFFSET;
                          X2R = X2 + DLR;
                          Y2R = Y2 - (WS >> 1) - OFFSET;

                        break;

            case UP     : X1R = X1 - (WS >> 1) - DWR - OFFSET;
                          Y1R = Y1 - DLR;
                          X2R = X2 - (WS >> 1) - OFFSET;
                          Y2R = Y2 + DLR;

                        break;

            case DOWN   : X1R = X1 + (WS >> 1) + OFFSET;
                          Y1R = Y1 - DLR;
                          X2R = X2 + (WS >> 1) + DWR + OFFSET;
                          Y2R = Y2 + DLR;

                        break;
          }
        }
        else
        if ( TRANS == RDS_TRANS_RCW )
        {
          switch ( Segment->TYPE )
          {
            case RIGHT  : X1R = X1 - DLR;
                          Y1R = Y1 - (WS >> 1) - DWR - OFFSET;
                          X2R = X2 + DLR;
                          Y2R = Y2 - (WS >> 1) - OFFSET;

                        break;

            case LEFT   : X1R = X1 - DLR;
                          Y1R = Y1 + (WS >> 1) + OFFSET;
                          X2R = X2 + DLR;
                          Y2R = Y2 + (WS >> 1) + DWR + OFFSET;

                        break;

            case UP     : X1R = X1 + (WS >> 1) + OFFSET;
                          Y1R = Y1 - DLR;
                          X2R = X2 + (WS >> 1) + DWR + OFFSET;
                          Y2R = Y2 + DLR;

                        break;

            case DOWN   : X1R = X1 - (WS >> 1) - DWR - OFFSET;
                          Y1R = Y1 - DLR;
                          X2R = X2 - (WS >> 1) - OFFSET;
                          Y2R = Y2 + DLR;

                        break;
          }
        }
      
        X1R = RfmRoundLow ( X1R );
        Y1R = RfmRoundLow ( Y1R );
        X2R = RfmRoundHigh( X2R );
        Y2R = RfmRoundHigh( Y2R );

        Rectangle = addrdsfigrec( Figure, Segment->NAME, 
                                  LayerRds, X1R, Y1R, 
                                  X2R - X1R, Y2R - Y1R );

        SetRdsSegment( Rectangle );

        if ( First == (rdsrec_list *)NULL )
        {
          First = Rectangle;
          Link  = Rectangle;
        }
        else
        {
          Link->USER = (void *)Rectangle;
          Link       = Rectangle;
        }
      }

      Index = Index + 1;

      LayerRds = GET_SEGMENT_LAYER( LayerMbk, Index );
    }

    if ( First != (rdsrec_list *)NULL ) Link->USER = (void *)First;

    return( First );
  }

/*------------------------------------------------------------\
|                                                             |
|                   MBK Via To RDS Rectangle                  |
|                                                             |
\------------------------------------------------------------*/

  rdsrec_list *viambkrds( Figure, Via )

     rdsfig_list *Figure;
     phvia_list  *Via;
  {
    rdsrec_list  *Rectangle;
    rdsrec_list  *First;
    rdsrec_list  *Link;

    long          Xvia;
    long          Yvia;

    long          X1R;
    long          Y1R;
    long          X2R;
    long          Y2R;

    long          SIZE;

    char          ViaMbk;
    char          LayerRds;
    char          Index;

    Rectangle = (rdsrec_list *)NULL;
    First     = (rdsrec_list *)NULL;
    Link      = (rdsrec_list *)NULL;

    Xvia = Via->XVIA * RDS_LAMBDA / SCALE_X;
    Yvia = Via->YVIA * RDS_LAMBDA / SCALE_X;
   
    ViaMbk    = Via->TYPE;
    Index     = 0;
    LayerRds  = GET_VIA_LAYER( ViaMbk, Index );

    while ( LayerRds != RDS_VIA_EMPTY )
    {
      SIZE = GET_VIA_SIZE( ViaMbk, Index );

      X1R = Xvia - ( SIZE >> 1 );
      Y1R = Yvia - ( SIZE >> 1 );
      X2R = Xvia + ( SIZE >> 1 );
      Y2R = Yvia + ( SIZE >> 1 );

      X1R = RfmRoundLow ( X1R );
      Y1R = RfmRoundLow ( Y1R );
      X2R = RfmRoundHigh( X2R );
      Y2R = RfmRoundHigh( Y2R );

      Rectangle = addrdsfigrec( Figure, (char *)NULL, 
                                LayerRds, X1R, Y1R,
                                X2R - X1R, Y2R - Y1R );

      SetRdsVia( Rectangle );

      if ( First == (rdsrec_list *)NULL )
      {
        First = Rectangle;
        Link  = Rectangle;
      }
      else
      {
        Link->USER = (void *)Rectangle;
        Link       = Rectangle;
      }

      Index = Index + 1;

      LayerRds = GET_VIA_LAYER( ViaMbk, Index );
    }

    if ( First != (rdsrec_list *)NULL ) Link->USER = (void *)First;
 
    return( First );
  }

/*------------------------------------------------------------\
|                                                             |
|                   MBK Ref To RDS Rectangle                  |
|                                                             |
\------------------------------------------------------------*/
  
  rdsrec_list *refmbkrds( Figure, Reference )

     rdsfig_list *Figure;
     phref_list  *Reference;
  {
    rdsrec_list  *Rectangle;

    long          Xref;
    long          Yref;

    long          X1R;
    long          Y1R;
    long          X2R;
    long          Y2R;

    long          SIZE;

    char          RefMbk;
    char          LayerRds;

    if ( RfmRefRef == (char *)NULL ) 
    {
      RfmRefRef = namealloc( "ref_ref" );
    }

    Rectangle = (rdsrec_list *)NULL;

    Xref = Reference->XREF * RDS_LAMBDA / SCALE_X;
    Yref = Reference->YREF * RDS_LAMBDA / SCALE_X;

    RefMbk    = (Reference->FIGNAME == RfmRefRef)? MBK_REF_REF:MBK_REF_CON;
    LayerRds  = GET_REFERENCE_LAYER( RefMbk );

    if ( LayerRds != RDS_REFERENCE_EMPTY )
    {
      SIZE = GET_REFERENCE_SIZE( RefMbk );

      X1R = Xref - ( SIZE >> 1 );
      Y1R = Yref - ( SIZE >> 1 );
      X2R = Xref + ( SIZE >> 1 );
      Y2R = Yref + ( SIZE >> 1 );

      X1R = RfmRoundLow ( X1R );
      Y1R = RfmRoundLow ( Y1R );
      X2R = RfmRoundHigh( X2R );
      Y2R = RfmRoundHigh( Y2R );

      Rectangle = addrdsfigrec( Figure, Reference->NAME, 
                                LayerRds, X1R, Y1R,
                                X2R - X1R, Y2R - Y1R );

      SetRdsReference( Rectangle );

      if ( RefMbk == MBK_REF_REF )
      {
        SetRdsRefRef( Rectangle );
      }
      else
      {
        SetRdsRefCon( Rectangle );
      }

      Rectangle->USER = (void *)Rectangle;
    }

    return( Rectangle );
  }

/*------------------------------------------------------------\
|                                                             |
|                  MBK Connector To RDS Rectangle             |
|                                                             |
\------------------------------------------------------------*/

  rdsrec_list *conmbkrds( Figure, Connector )

     rdsfig_list *Figure;
     phcon_list  *Connector;
  {
    rdsrec_list  *Rectangle;

    long          Xcon;
    long          Ycon;

    long          X1R;
    long          Y1R;
    long          X2R;
    long          Y2R;
    long          WS;

    long          DWR;
    long          DER;

    char          LayerMbk;
    char          LayerRds;

    Rectangle = (rdsrec_list *)NULL;

    Xcon = Connector->XCON  * RDS_LAMBDA / SCALE_X;
    Ycon = Connector->YCON  * RDS_LAMBDA / SCALE_X;
    WS   = Connector->WIDTH * RDS_LAMBDA / SCALE_X;
      
    LayerMbk  = Connector->LAYER;
    LayerRds  = GET_CONNECTOR_LAYER( LayerMbk );
      
    if ( LayerRds != RDS_CONNECTOR_EMPTY )
    {
      DWR = GET_CONNECTOR_DWR( LayerMbk );
      DER = GET_CONNECTOR_DER( LayerMbk );

      if ( ( Connector->ORIENT == EAST ) || 
           ( Connector->ORIENT == WEST ) )
      {
        X1R = Xcon - DER;
        Y1R = Ycon - (( WS + DWR ) >> 1);
        X2R = Xcon + DER;
        Y2R = Ycon + (( WS + DWR ) >> 1);
      }
      else
      {
        X1R = Xcon - (( WS + DWR ) >> 1);
        Y1R = Ycon - DER;
        X2R = Xcon + (( WS + DWR ) >> 1);
        Y2R = Ycon + DER;
      }
 
      X1R = RfmRoundLow ( X1R );
      Y1R = RfmRoundLow ( Y1R );
      X2R = RfmRoundHigh( X2R );
      Y2R = RfmRoundHigh( Y2R );

      Rectangle = addrdsfigrec( Figure, Connector->NAME, 
                                LayerRds, X1R, Y1R,
                                X2R - X1R, Y2R - Y1R );
 
      SetRdsConnector( Rectangle );
      SetRdsConExter( Rectangle );

      Rectangle->USER = (void *)Rectangle;
    }

    return( Rectangle );
  }

/*------------------------------------------------------------\
|                                                             |
|            MBK Instance Segment To RDS Rectangle            |
|                                                             |
\------------------------------------------------------------*/
  
  rdsrec_list *inssegmbkrds( InstanceMbk, ModelMbk, InstanceRds, Lynx )

     phins_list  *InstanceMbk;
     phfig_list  *ModelMbk;
     rdsins_list *InstanceRds;
     char         Lynx;
  {
    phseg_list   *Segment;
    rdsrec_list  *Rectangle;
    rdsrec_list  *First;
    rdsrec_list  *Link;

    long          X1;
    long          Y1;
    long          X2;
    long          Y2;
    long          WS;

    long          X1R;
    long          Y1R;
    long          X2R;
    long          Y2R;

    long          DLR;
    long          DWR;
    long          OFFSET;
    char          TRANS;
    char          USE;
    long          Swap;

    char          LayerMbk;
    char          LayerRds;
    char          Index;
    char          Type;

    Rectangle = (rdsrec_list *)NULL;
    First     = (rdsrec_list *)NULL;
    Link      = (rdsrec_list *)NULL;

    for ( Segment  = ModelMbk->PHSEG;
          Segment != (phseg_list *)NULL;
          Segment  = Segment->NEXT )
    { 
      LayerMbk = Segment->LAYER;

      xyflat
      ( &X1                  , &Y1,
        Segment->X1          , Segment->Y1,
        InstanceMbk->XINS    , InstanceMbk->YINS,
        ModelMbk->XAB1       , ModelMbk->YAB1,
        ModelMbk->XAB2       , ModelMbk->YAB2,
        InstanceMbk->TRANSF
      );
  
      xyflat
      ( &X2                  , &Y2, 
        Segment->X2          , Segment->Y2,
        InstanceMbk->XINS    , InstanceMbk->YINS,
        ModelMbk->XAB1       , ModelMbk->YAB1,
        ModelMbk->XAB2       , ModelMbk->YAB2,
        InstanceMbk->TRANSF
      );

      if ( X1 < X2 ) Type = RIGHT;
      if ( Y1 < Y2 ) Type = UP;
      if ( X1 > X2 ) { Swap = X1; X1 = X2; X2 = Swap; Type = LEFT; }
      if ( Y1 > Y2 ) { Swap = Y1; Y1 = Y2; Y2 = Swap; Type = DOWN; }
  
      X1 = X1             * RDS_LAMBDA / SCALE_X;
      X2 = X2             * RDS_LAMBDA / SCALE_X;
      Y1 = Y1             * RDS_LAMBDA / SCALE_X;
      Y2 = Y2             * RDS_LAMBDA / SCALE_X;
      WS = Segment->WIDTH * RDS_LAMBDA / SCALE_X;

      Index     = 0;
      LayerRds  = GET_SEGMENT_LAYER( LayerMbk, Index );
  
      while ( LayerRds != RDS_SEGMENT_EMPTY )
      {
        TRANS  = GET_SEGMENT_TRANS ( LayerMbk, Index );
        DLR    = GET_SEGMENT_DLR   ( LayerMbk, Index );
        DWR    = GET_SEGMENT_DWR   ( LayerMbk, Index );
        OFFSET = GET_SEGMENT_OFFSET( LayerMbk, Index );
        USE    = GET_SEGMENT_USE   ( LayerMbk, Index );

        if ( ( ( USE == RDS_USE_ALL     )               ) ||
             ( ( USE == RDS_USE_EXTRACT ) && (   Lynx ) ) ||
             ( ( USE == RDS_USE_DRC     ) && ( ! Lynx ) ) )
        {
          if ( TRANS == RDS_TRANS_VW )
          {
            switch ( Type )
            {
              case LEFT   : X1R = X1 - DLR;
                            Y1R = Y1 - ( ( WS + DWR ) >> 1 ) + OFFSET;
                            X2R = X2 + DLR;
                            Y2R = Y2 + ( ( WS + DWR ) >> 1 ) + OFFSET;

                          break;

              case RIGHT  : X1R = X1 - DLR;
                            Y1R = Y1 - ( ( WS + DWR ) >> 1 ) - OFFSET;
                            X2R = X2 + DLR;
                            Y2R = Y2 + ( ( WS + DWR ) >> 1 ) - OFFSET;

                          break;

              case DOWN   : X1R = X1 - ( ( WS + DWR ) >> 1 ) - OFFSET;
                            Y1R = Y1 - DLR;
                            X2R = X2 + ( ( WS + DWR ) >> 1 ) - OFFSET;
                            Y2R = Y2 + DLR;

                          break;

              case UP     : X1R = X1 - ( ( WS + DWR ) >> 1 ) + OFFSET;
                            Y1R = Y1 - DLR;
                            X2R = X2 + ( ( WS + DWR ) >> 1 ) + OFFSET;
                            Y2R = Y2 + DLR;

                          break;
            }
          }
          else
          if ( TRANS == RDS_TRANS_LCW )
          {
            switch ( Type )
            {
              case RIGHT  : X1R = X1 - DLR;
                            Y1R = Y1 + (WS >> 1) + OFFSET;
                            X2R = X2 + DLR;
                            Y2R = Y2 + (WS >> 1) + DWR + OFFSET;

                          break;

              case LEFT   : X1R = X1 - DLR;
                            Y1R = Y1 - (WS >> 1) - DWR - OFFSET;
                            X2R = X2 + DLR;
                            Y2R = Y2 - (WS >> 1) - OFFSET;

                          break;

              case UP     : X1R = X1 - (WS >> 1) - DWR - OFFSET;
                            Y1R = Y1 - DLR;
                            X2R = X2 - (WS >> 1) - OFFSET;
                            Y2R = Y2 + DLR;

                          break;

              case DOWN   : X1R = X1 + (WS >> 1) + OFFSET;
                            Y1R = Y1 - DLR;
                            X2R = X2 + (WS >> 1) + DWR + OFFSET;
                            Y2R = Y2 + DLR;

                          break;
            }
          }
          else
          if ( TRANS == RDS_TRANS_RCW )
          {
            switch ( Type )
            {
              case RIGHT  : X1R = X1 - DLR;
                            Y1R = Y1 - (WS >> 1) - DWR - OFFSET;
                            X2R = X2 + DLR;
                            Y2R = Y2 - (WS >> 1) - OFFSET;

                          break;

              case LEFT   : X1R = X1 - DLR;
                            Y1R = Y1 + (WS >> 1) + OFFSET;
                            X2R = X2 + DLR;
                            Y2R = Y2 + (WS >> 1) + DWR + OFFSET;

                          break;

              case UP     : X1R = X1 + (WS >> 1) + OFFSET;
                            Y1R = Y1 - DLR;
                            X2R = X2 + (WS >> 1) + DWR + OFFSET;
                            Y2R = Y2 + DLR;

                          break;

              case DOWN   : X1R = X1 - (WS >> 1) - DWR - OFFSET;
                            Y1R = Y1 - DLR;
                            X2R = X2 - (WS >> 1) - OFFSET;
                            Y2R = Y2 + DLR;

                          break;
            }
          }

          X1R = RfmRoundLow ( X1R );
          Y1R = RfmRoundLow ( Y1R );
          X2R = RfmRoundHigh( X2R );
          Y2R = RfmRoundHigh( Y2R );
  
          Rectangle = addrdsinsrec( InstanceRds, Segment->NAME, 
                                    LayerRds, X1R, Y1R,
                                    X2R - X1R, Y2R - Y1R );
  
          SetRdsSegment( Rectangle );
  
          if ( First == (rdsrec_list *)NULL )
          {
            First = Rectangle;
            Link  = Rectangle;
          }
          else
          {
            Link->USER = (void *)Rectangle;
            Link       = Rectangle;
          }
        }

        Index = Index + 1;
  
        LayerRds = GET_SEGMENT_LAYER( LayerMbk, Index );
      }
    }
  
    if ( First != (rdsrec_list *)NULL ) Link->USER = (void *)First;

    return( First );
  }

/*------------------------------------------------------------\
|                                                             |
|               MBK Instance Via To RDS Rectangle             |
|                                                             |
\------------------------------------------------------------*/
  
  rdsrec_list *insviambkrds( InstanceMbk, ModelMbk, InstanceRds )

     phins_list  *InstanceMbk;
     phfig_list  *ModelMbk;
     rdsins_list *InstanceRds;
  {
    phvia_list   *Via;
    rdsrec_list  *Rectangle;
    rdsrec_list  *First;
    rdsrec_list  *Link;

    long          Xvia;
    long          Yvia;

    long          X1R;
    long          Y1R;
    long          X2R;
    long          Y2R;

    long          SIZE;

    char          ViaMbk;
    char          LayerRds;
    char          Index;

    Rectangle = (rdsrec_list *)NULL;
    First     = (rdsrec_list *)NULL;
    Link      = (rdsrec_list *)NULL;

    for ( Via  = ModelMbk->PHVIA;
          Via != (phvia_list *)NULL;
          Via  = Via->NEXT )
    {
      xyflat
      ( &Xvia              , &Yvia,
        Via->XVIA          , Via->YVIA,
        InstanceMbk->XINS  , InstanceMbk->YINS,
        ModelMbk->XAB1     , ModelMbk->YAB1,
        ModelMbk->XAB2     , ModelMbk->YAB2,
        InstanceMbk->TRANSF
      );

      Xvia = Xvia * RDS_LAMBDA / SCALE_X;
      Yvia = Yvia * RDS_LAMBDA / SCALE_X;
   
      ViaMbk    = Via->TYPE;
      Index     = 0;
      LayerRds  = GET_VIA_LAYER( ViaMbk, Index );

      while ( LayerRds != RDS_VIA_EMPTY )
      {
        SIZE = GET_VIA_SIZE( ViaMbk, Index );

        X1R = Xvia - ( SIZE >> 1 );
        Y1R = Yvia - ( SIZE >> 1 );
        X2R = Xvia + ( SIZE >> 1 );
        Y2R = Yvia + ( SIZE >> 1 );

        X1R = RfmRoundLow ( X1R );
        Y1R = RfmRoundLow ( Y1R );
        X2R = RfmRoundHigh( X2R );
        Y2R = RfmRoundHigh( Y2R );

        Rectangle = addrdsinsrec( InstanceRds, (char *)NULL, 
                                  LayerRds, X1R, Y1R,
                                  X2R - X1R, Y2R - Y1R );

        SetRdsVia( Rectangle );

        if ( First == (rdsrec_list *)NULL )
        {
          First = Rectangle;
          Link  = Rectangle;
        }
        else
        {
          Link->USER = (void *)Rectangle;
          Link       = Rectangle;
        }

        Index = Index + 1;

        LayerRds = GET_VIA_LAYER( ViaMbk, Index );
      }
    }

    if ( First != (rdsrec_list *)NULL ) Link->USER = (void *)First;
 
    return( First );
  }
  
/*------------------------------------------------------------\
|                                                             |
|          MBK Instance Reference To RDS Rectangle            |
|                                                             |
\------------------------------------------------------------*/

  rdsrec_list *insrefmbkrds( InstanceMbk, ModelMbk, InstanceRds )

     phins_list  *InstanceMbk;
     phfig_list  *ModelMbk;
     rdsins_list *InstanceRds;

  {
    phref_list   *Reference;
    rdsrec_list  *Rectangle;
    rdsrec_list  *First;
    rdsrec_list  *Link;

    long          Xref;
    long          Yref;

    long          X1R;
    long          Y1R;
    long          X2R;
    long          Y2R;

    long          SIZE;

    char          RefMbk;
    char          LayerRds;

    if ( RfmRefRef == (char *)NULL ) 
    {
      RfmRefRef = namealloc( "ref_ref" );
    }

    Rectangle = (rdsrec_list *)NULL;
    First     = (rdsrec_list *)NULL;
    Link      = (rdsrec_list *)NULL;

    for ( Reference  = ModelMbk->PHREF;
          Reference != (phref_list *)NULL;
          Reference  = Reference->NEXT )
    { 
      xyflat
      ( &Xref              , &Yref,
        Reference->XREF    , Reference->YREF,
        InstanceMbk->XINS  , InstanceMbk->YINS,
        ModelMbk->XAB1     , ModelMbk->YAB1,
        ModelMbk->XAB2     , ModelMbk->YAB2,
        InstanceMbk->TRANSF
      );
  
      Xref = Xref * RDS_LAMBDA / SCALE_X;
      Yref = Yref * RDS_LAMBDA / SCALE_X;

      RefMbk    = (Reference->FIGNAME == RfmRefRef)? MBK_REF_REF:MBK_REF_CON;
      LayerRds  = GET_REFERENCE_LAYER( RefMbk );

      if ( LayerRds != RDS_REFERENCE_EMPTY )
      {
        SIZE = GET_REFERENCE_SIZE( RefMbk );

        X1R = Xref - ( SIZE >> 1 );
        Y1R = Yref - ( SIZE >> 1 );
        X2R = Xref + ( SIZE >> 1 );
        Y2R = Yref + ( SIZE >> 1 );

        X1R = RfmRoundLow ( X1R );
        Y1R = RfmRoundLow ( Y1R );
        X2R = RfmRoundHigh( X2R );
        Y2R = RfmRoundHigh( Y2R );
  
        Rectangle = addrdsinsrec( InstanceRds, Reference->NAME,
                                  LayerRds, X1R, Y1R,
                                  X2R - X1R, Y2R - Y1R );

        SetRdsReference( Rectangle );

        if ( RefMbk == MBK_REF_REF )
        {
          SetRdsRefRef( Rectangle );
        }
        else
        {   
          SetRdsRefCon( Rectangle );
        }

        if ( First == (rdsrec_list *)NULL )
        {
          First = Rectangle;
          Link  = Rectangle;
        }
        else
        {   
          Link->USER = (void *)Rectangle;
          Link       = Rectangle;
        }
      }  
    }
  
    if ( First != (rdsrec_list *)NULL ) Link->USER = (void *)First;

    return( First );
  }

/*------------------------------------------------------------\
|                                                             |
|          MBK Instance Connector To RDS Rectangle            |
|                                                             |
\------------------------------------------------------------*/

  rdsrec_list *insconmbkrds( InstanceMbk, ModelMbk, InstanceRds )

     phins_list  *InstanceMbk;
     phfig_list  *ModelMbk;
     rdsins_list *InstanceRds;
 {
    phcon_list   *Connector;
    rdsrec_list  *Rectangle;
    rdsrec_list  *First;
    rdsrec_list  *Link;

    long          Xcon;
    long          Ycon;

    long          X1R;
    long          Y1R;
    long          X2R;
    long          Y2R;
    long          WS;

    long          DWR;
    long          DER;

    char          Orient;
    char          LayerMbk;
    char          LayerRds;

    Rectangle = (rdsrec_list *)NULL;
    First     = (rdsrec_list *)NULL;
    Link      = (rdsrec_list *)NULL;

    for ( Connector  = ModelMbk->PHCON;
          Connector != (phcon_list *)NULL;
          Connector  = Connector->NEXT )
    {
      xyflat
      ( &Xcon               , &Ycon,
        Connector->XCON     , Connector->YCON,
        InstanceMbk->XINS   , InstanceMbk->YINS,
        ModelMbk->XAB1      , ModelMbk->YAB1,
        ModelMbk->XAB2      , ModelMbk->YAB2,
        InstanceMbk->TRANSF
      );
       
      Xcon = Xcon             * RDS_LAMBDA / SCALE_X;
      Ycon = Ycon             * RDS_LAMBDA / SCALE_X;
      WS   = Connector->WIDTH * RDS_LAMBDA / SCALE_X;

      LayerMbk  = Connector->LAYER;
      LayerRds  = GET_CONNECTOR_LAYER( LayerMbk );

      if ( LayerRds != RDS_REFERENCE_EMPTY )
      {
        DWR    = GET_CONNECTOR_DWR( LayerMbk );
        DER    = GET_CONNECTOR_DER( LayerMbk );
        Orient = RfmNewConnectorOrient[ InstanceMbk->TRANSF ];
 
        if ( ( Connector->ORIENT == EAST ) ||
             ( Connector->ORIENT == WEST ) )
        {
          Orient = ! Orient;
        }

        if ( Orient != 1 )  /* EAST AND WEST */
        {
          X1R = Xcon - DER;
          Y1R = Ycon - ( ( WS + DWR ) >> 1 );
          X2R = Xcon + DER;
          Y2R = Ycon + ( ( WS + DWR ) >> 1 );
        }
        else
        {
          X1R = Xcon - ( ( WS + DWR ) >> 1 );
          Y1R = Ycon - DER;
          X2R = Xcon + ( ( WS + DWR ) >> 1 );
          Y2R = Ycon + DER; 
        }

        X1R = RfmRoundLow ( X1R );
        Y1R = RfmRoundLow ( Y1R );
        X2R = RfmRoundHigh( X2R );
        Y2R = RfmRoundHigh( Y2R );
 
        Rectangle = addrdsinsrec( InstanceRds, Connector->NAME,
                                  LayerRds, X1R, Y1R, 
                                  X2R - X1R, Y2R - Y1R );
 
        SetRdsConnector( Rectangle );
        SetRdsConInter( Rectangle );

        if ( First == (rdsrec_list *)NULL )
        {
          First = Rectangle;
          Link  = Rectangle;
        }
        else
        {   
          Link->USER = (void *)Rectangle;
          Link       = Rectangle;
        }
      }
    }  

    if ( First != (rdsrec_list *)NULL ) Link->USER = (void *)First;

    return( First );
  }

/*------------------------------------------------------------\
|                                                             |
|                MBK Instance To RDS Instance                 |
|                                                             |
\------------------------------------------------------------*/

  rdsins_list *insmbkrds( FigureRds, InstanceMbk, Mode, Lynx )

     rdsfig_list *FigureRds;
     phins_list  *InstanceMbk;
     char         Mode;
     char         Lynx;
  {
    rdsins_list *InstanceRds;
    rdsrec_list *Rectangle;
    phfig_list  *ModelMbk;

    long         Xins;
    long         Yins;
    long         Xab1;
    long         Xab2;
    long         Yab1;
    long         Yab2;
    long         DX;
    long         DY;
    long         Swap;

    ModelMbk = getphfig( InstanceMbk->FIGNAME, Mode );

    xyflat
    ( &Xins              , &Yins,
      0                  , 0,
      InstanceMbk->XINS  , InstanceMbk->YINS,
      ModelMbk->XAB1     , ModelMbk->YAB1,
      ModelMbk->XAB2     , ModelMbk->YAB2,
      InstanceMbk->TRANSF
    );

    xyflat
    ( &Xab1              , &Yab1,
      ModelMbk->XAB1     , ModelMbk->YAB1,
      InstanceMbk->XINS  , InstanceMbk->YINS,
      ModelMbk->XAB1     , ModelMbk->YAB1,
      ModelMbk->XAB2     , ModelMbk->YAB2,
      InstanceMbk->TRANSF
    );
 
    xyflat
    ( &Xab2              , &Yab2,
      ModelMbk->XAB2     , ModelMbk->YAB2,
      InstanceMbk->XINS  , InstanceMbk->YINS,
      ModelMbk->XAB1     , ModelMbk->YAB1,
      ModelMbk->XAB2     , ModelMbk->YAB2,
      InstanceMbk->TRANSF
    );

    Xins = RfmRoundLow( Xins * RDS_LAMBDA / SCALE_X );
    Yins = RfmRoundLow( Yins * RDS_LAMBDA / SCALE_X );
    Xab1 = RfmRoundLow( Xab1 * RDS_LAMBDA / SCALE_X );
    Yab1 = RfmRoundLow( Yab1 * RDS_LAMBDA / SCALE_X );
    Xab2 = RfmRoundHigh( Xab2 * RDS_LAMBDA / SCALE_X );
    Yab2 = RfmRoundHigh( Yab2 * RDS_LAMBDA / SCALE_X );
 
    InstanceRds = addrdsins( FigureRds, 
                             InstanceMbk->FIGNAME, InstanceMbk->INSNAME,
                             InstanceMbk->TRANSF,
                             Xins, Yins );

    if ( Xab1 > Xab2 ) { Swap = Xab1; Xab1 = Xab2; Xab2 = Swap; }
    if ( Yab1 > Yab2 ) { Swap = Yab1; Yab1 = Yab2; Yab2 = Swap; }
   
    Rectangle = addrdsinsrec( InstanceRds, InstanceMbk->INSNAME,
                              RDS_ABOX, Xab1, Yab1, Xab2 - Xab1, Yab2 - Yab1 );

    SetRdsInstance( Rectangle );

    Rectangle->USER = (void *)Rectangle;

    inssegmbkrds( InstanceMbk, ModelMbk, InstanceRds, Lynx );
    insconmbkrds( InstanceMbk, ModelMbk, InstanceRds       );
    insrefmbkrds( InstanceMbk, ModelMbk, InstanceRds       );
    insviambkrds( InstanceMbk, ModelMbk, InstanceRds       );
 
    return( InstanceRds );
  }

/*------------------------------------------------------------\
|                                                             |
|                      MBK Abox to RDS Abox                   |
|                                                             |
\------------------------------------------------------------*/

   rdsrec_list *aboxmbkrds( FigureMbk, FigureRds )
 
     phfig_list  *FigureMbk;
     rdsfig_list *FigureRds;
  {
    rdsrec_list *Rectangle;
    long         XAB1;
    long         XAB2;
    long         YAB1;
    long         YAB2;

    XAB1 = RfmRoundLow( FigureMbk->XAB1 * RDS_LAMBDA / SCALE_X );
    XAB2 = RfmRoundLow( FigureMbk->XAB2 * RDS_LAMBDA / SCALE_X );
    YAB1 = RfmRoundHigh( FigureMbk->YAB1 * RDS_LAMBDA / SCALE_X );
    YAB2 = RfmRoundHigh( FigureMbk->YAB2 * RDS_LAMBDA / SCALE_X );

    if ( ( XAB1 != 0 ) || ( XAB2 != 0 ) ||
         ( YAB1 != 0 ) || ( YAB2 != 0 ) )
    {
      Rectangle = 
   
        addrdsfigrec( FigureRds, FigureMbk->NAME, 
                      RDS_ABOX, 
                      XAB1, YAB1, XAB2 - XAB1, YAB2 - YAB1 );

      SetRdsFigure( Rectangle );

      Rectangle->USER = (void *)Rectangle;

      return( Rectangle );
    }

    return( (rdsrec_list *)NULL );
  }   

/*------------------------------------------------------------\
|                                                             |
|                    MBK Figure To RDS Figure                 |
|                                                             |
\------------------------------------------------------------*/

  rdsfig_list *figmbkrds( FigureMbk, Size, Lynx )
  
     phfig_list   *FigureMbk;
     unsigned int  Size;
     char          Lynx;
  {
    rdsfig_list *FigureRds;
    void        *Pointer;

    FigureRds = addrdsfig( FigureMbk->NAME, Size );

    aboxmbkrds( FigureMbk, FigureRds );

    for ( Pointer  = (void *)(FigureMbk->PHSEG);
          Pointer != (void *)NULL;
          Pointer  = (void *)(((phseg_list *)Pointer)->NEXT))
    {
      segmbkrds( FigureRds, (phseg_list *)Pointer, Lynx );
    }

    for ( Pointer  = (void *)(FigureMbk->PHCON);
          Pointer != (void *)NULL;
          Pointer  = (void *)(((phcon_list *)Pointer)->NEXT))
    {
      conmbkrds( FigureRds, (phcon_list *)Pointer);
    }

    for ( Pointer  = (void *)(FigureMbk->PHREF);
          Pointer != (void *)NULL;
          Pointer  = (void *)(((phref_list *)Pointer)->NEXT))
    {
      refmbkrds( FigureRds, (phref_list *)Pointer);
    }

    for ( Pointer  = (void *)(FigureMbk->PHVIA);
          Pointer != (void *)NULL;
          Pointer  = (void *)(((phvia_list *)Pointer)->NEXT))
    {
      viambkrds( FigureRds, (phvia_list *)Pointer);
    }
 
    for ( Pointer  = (void *)(FigureMbk->PHINS);
          Pointer != (void *)NULL;
          Pointer  = (void *)(((phins_list *)Pointer)->NEXT))
    {
      insmbkrds( FigureRds, (phins_list *)Pointer, 'P', Lynx );
    }

    return( FigureRds );
  }

/*------------------------------------------------------------\
|                                                             |
|                       Model Mbk To Rds                      |
|                                                             |
\------------------------------------------------------------*/

  rdsfig_list *modelmbkrds( Figure, Lynx )

    rdsfig_list *Figure;
    char         Lynx;
  {
    rdsfig_list  *HeadFig;
    rdsfig_list  *StopFig;
    rdsfig_list  *ScanFig;
    rdsfig_list **Previous;
    phfig_list   *FigureMbk;
    rdsins_list  *Instance;


    ScanFig  = HEAD_RDSFIG;
    Previous = &HEAD_RDSFIG;

    while ( ScanFig != (rdsfig_list *)NULL )
    {
      if ( ScanFig == Figure ) break;

      Previous = &ScanFig->NEXT;
      ScanFig  = ScanFig->NEXT;
    }

    if ( ScanFig == (rdsfig_list *)NULL ) 
    {
      return( (rdsfig_list *)NULL );
    }

    *Previous     = Figure->NEXT;
    Figure->NEXT  = HEAD_RDSFIG;
    HEAD_RDSFIG   = Figure;

    StopFig = Figure->NEXT;

    do
    {
      HeadFig = HEAD_RDSFIG;

      for ( ScanFig  = HeadFig;
            ScanFig != StopFig;
            ScanFig  = ScanFig->NEXT )
      {
        for ( Instance  = ScanFig->INSTANCE;
              Instance != (rdsins_list *)NULL;
              Instance  = Instance->NEXT )
        {
          if ( searchrdsfig( Instance->FIGNAME ) == (rdsfig_list *)NULL )
          {
            FigureMbk = getphfig( Instance->FIGNAME, 'A' );
            figmbkrds( FigureMbk, Figure->SIZE, Lynx );
          }
        }
      }

      StopFig = HeadFig;
    }
    while ( HeadFig != HEAD_RDSFIG );

    return( HEAD_RDSFIG );
  }

/*------------------------------------------------------------\
|                                                             |
|                       View Functions                        |
|                                                             |
\------------------------------------------------------------*/
/*------------------------------------------------------------\
|                                                             |
|                   View Linked Rectangle                     |
|                                                             |
\------------------------------------------------------------*/

  void viewrfmrec( Rectangle )

     rdsrec_list *Rectangle;
  {
    rdsrec_list *Scan;
    char        *LayerName;

    long         X;
    long         Y;
    long         DX;
    long         DY;

    Scan = Rectangle;

    if ( Scan != (rdsrec_list *)NULL )
    {
      do
      {
        LayerName = RDS_LAYER_NAME[ GetRdsLayer( Scan ) ];

        fprintf( stdout, "\n--> in rectangle" );

        X  = Scan->X  * SCALE_X / RDS_LAMBDA;
        Y  = Scan->Y  * SCALE_X / RDS_LAMBDA;
        DX = Scan->DX * SCALE_X / RDS_LAMBDA;
        DY = Scan->DY * SCALE_X / RDS_LAMBDA;

        if ( Scan->NAME != (char *)NULL )
        {
          fprintf( stdout, "\n\tNAME  : %s" , Scan->NAME  );
        }
        else
        {
          fprintf( stdout, "\n\tNAME  : NO NAME" );
        }

        fprintf( stdout, "\n\tX     : %ld" , X           );
        fprintf( stdout, "\n\tY     : %ld" , Y           );
        fprintf( stdout, "\n\tDX    : %ld" , DX          );
        fprintf( stdout, "\n\tDY    : %ld" , DY          );
        fprintf( stdout, "\n\tFLAGS : %l0X", Scan->FLAGS );
        fprintf( stdout, "\n\tLAYER : %s"  , LayerName   );

        Scan = (rdsrec_list *)(Scan->USER);
      }
      while ( Scan != Rectangle );
    }
  } 

/*------------------------------------------------------------\
|                                                             |
|                   View Segment Translation                  |
|                                                             |
\------------------------------------------------------------*/

  void viewrfmseg( Segment, Rectangle )

     phseg_list  *Segment;
     rdsrec_list *Rectangle;
  {
    char *LayerName;

    LayerName = MBK_LAYER_NAME[ Segment->LAYER ];

    fprintf( stdout, "\n--> Translate segment" );

    if ( Segment->NAME != (char *)NULL )
    {
      fprintf( stdout, "\n\tNAME  : %s" , Segment->NAME  );
    }
    else
    {
      fprintf( stdout, "\n\tNAME  : NO NAME" );
    }

    fprintf( stdout, "\n\tX1    : %ld", Segment->X1    );
    fprintf( stdout, "\n\tY1    : %ld", Segment->Y1    );
    fprintf( stdout, "\n\tX2    : %ld", Segment->X2    );
    fprintf( stdout, "\n\tY2    : %ld", Segment->Y2    );
    fprintf( stdout, "\n\tWIDTH : %ld", Segment->WIDTH );
    fprintf( stdout, "\n\tLAYER : %s" , LayerName      );

    viewrfmrec( Rectangle );

    fprintf( stdout, "\n<-- End" );
  }

/*------------------------------------------------------------\
|                                                             |
|                      View Via Translation                   |
|                                                             |
\------------------------------------------------------------*/

  void viewrfmvia( Via, Rectangle )

     phvia_list  *Via;
     rdsrec_list *Rectangle;
  {
    char *ViaName;
 
    ViaName = MBK_VIA_NAME[ Via->TYPE ];

    fprintf( stdout, "\n--> Translate via" );

    fprintf( stdout, "\n\tXVIA  : %ld", Via->XVIA );
    fprintf( stdout, "\n\tYVIA  : %ld", Via->YVIA );
    fprintf( stdout, "\n\tTYPE  : %s" , ViaName   );
   
    viewrfmrec( Rectangle );

    fprintf( stdout, "\n<-- End" );
  }

/*------------------------------------------------------------\
|                                                             |
|                   View Reference Translation                |
|                                                             |
\------------------------------------------------------------*/

  void viewrfmref( Reference, Rectangle )

     phref_list  *Reference;
     rdsrec_list *Rectangle;
  {
    fprintf( stdout, "\n--> Translate reference" );

    fprintf( stdout, "\n\tXREF  : %ld", Reference->XREF    );
    fprintf( stdout, "\n\tYREF  : %ld", Reference->YREF    );
    fprintf( stdout, "\n\tTYPE  : %s" , Reference->FIGNAME );

    viewrfmrec( Rectangle );

    fprintf( stdout, "\n<-- End" );
  }

/*------------------------------------------------------------\
|                                                             |
|                   View Connector Translation                |
|                                                             |
\------------------------------------------------------------*/

  void viewrfmcon( Connector, Rectangle )

    phcon_list  *Connector;
    rdsrec_list *Rectangle;
  {
    char *LayerName;

    LayerName = MBK_LAYER_NAME[ Connector->LAYER ];

    fprintf( stdout, "\n--> Translate connector" );

    if ( Connector->NAME != (char *)NULL )
    {
      fprintf( stdout, "\n\tNAME   : %s" , Connector->NAME  );
    }
    else
    {
      fprintf( stdout, "\n\tNAME   : NO NAME" );
    }

    fprintf( stdout, "\n\tXCON   : %ld", Connector->XCON  );
    fprintf( stdout, "\n\tYCON   : %ld", Connector->YCON  );
    fprintf( stdout, "\n\tWIDTH  : %ld", Connector->WIDTH );
    fprintf( stdout, "\n\tLAYER  : %s" , LayerName        );

    viewrfmrec( Rectangle );

    fprintf( stdout, "\n<-- End" );
  }

/*------------------------------------------------------------\
|                                                             |
|                    View Instance Translation                |
|                                                             |
\------------------------------------------------------------*/

  void viewrfmins( InstanceMbk, InstanceRds )

     phins_list  *InstanceMbk;
     rdsins_list *InstanceRds;
  {
    char *TransfName;

    long  X;
    long  Y;

    TransfName = RDS_TRANSF_NAME[ InstanceMbk->TRANSF ];

    fprintf( stdout, "\n--> Translate instance" );

    fprintf( stdout, "\n\tINSNAME : %s" , InstanceMbk->INSNAME );
    fprintf( stdout, "\n\tFIGNAME : %s" , InstanceMbk->FIGNAME );
    fprintf( stdout, "\n\tXINS    : %ld", InstanceMbk->XINS    );
    fprintf( stdout, "\n\tYINS    : %ld", InstanceMbk->YINS    );
    fprintf( stdout, "\n\tTRANSF  : %s" , TransfName           );

    TransfName = RDS_TRANSF_NAME[ InstanceRds->TRANSF ];

    fprintf( stdout, "\n--> in instance" );

    X = InstanceRds->X * SCALE_X / RDS_LAMBDA;
    Y = InstanceRds->Y * SCALE_X / RDS_LAMBDA;
 
    fprintf( stdout, "\n\tINSNAME : %s" , InstanceRds->INSNAME );
    fprintf( stdout, "\n\tFIGNAME : %s" , InstanceRds->FIGNAME );
    fprintf( stdout, "\n\tX       : %ld", X                    );
    fprintf( stdout, "\n\tY       : %ld", Y                    );
    fprintf( stdout, "\n\tTRANSF  : %s" , TransfName           );
    fprintf( stdout, "\n\tSIZE    : %d" , InstanceRds->SIZE    );

    fprintf( stdout, "\n<-- End" );
  }

/*------------------------------------------------------------\
|                                                             |
|                      View Figure Translation                |
|                                                             |
\------------------------------------------------------------*/

  void viewrfmfig( FigureMbk, FigureRds )

     phfig_list  *FigureMbk;
     rdsfig_list *FigureRds;
  {
    fprintf( stdout, "\n--> Translate figure" );

    fprintf( stdout, "\n\tNAME : %s" , FigureMbk->NAME );

    fprintf( stdout, "\n--> in figure" );
 
    fprintf( stdout, "\n\tNAME : %s" , FigureRds->NAME );
    fprintf( stdout, "\n\tMODE : %c" , FigureRds->MODE );
    fprintf( stdout, "\n\tSIZE : %d" , FigureRds->SIZE );

    fprintf( stdout, "\n<-- End" );
  }

/*------------------------------------------------------------\
|                                                             |
|                     Round Rds Rectangle                     |
|                                                             |
\------------------------------------------------------------*/

  void roundrdsrec( Rectangle )

     rdsrec_list *Rectangle;
  {
     long X2, Y2;

     X2 = RfmRoundHigh( Rectangle->X + Rectangle->DX );
     Y2 = RfmRoundHigh( Rectangle->Y + Rectangle->DY );

     Rectangle->X  = RfmRoundLow( Rectangle->X );
     Rectangle->Y  = RfmRoundLow( Rectangle->Y );
     Rectangle->DX = X2 - Rectangle->X;
     Rectangle->DY = Y2 - Rectangle->Y;
  }
