⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ttraster.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/****************************************************************************//*                                                                          *//* Function:    New_Profile                                                 *//*                                                                          *//* Description: Creates a new Profile in the render pool.                   *//*                                                                          *//* Input:       aState   state/orientation of the new Profile               *//*                                                                          *//* Returns:     SUCCESS on success.                                         *//*              FAILURE in case of overflow or of incoherent Profile.       *//*                                                                          *//****************************************************************************/  static Bool  New_Profile( RAS_ARGS TStates  aState )  {    if ( !ras.fProfile )    {      ras.cProfile  = (PProfile)ras.top;      ras.fProfile  = ras.cProfile;      ras.top      += AlignProfileSize;    }    if ( ras.top >= ras.maxBuff )    {      ras.error = Raster_Err_Overflow;      return FAILURE;    }    switch ( aState )    {    case Ascending:      ras.cProfile->flow = TT_Flow_Up;      PTRACE7(( "New ascending profile = %lx\n", (long)ras.cProfile ));      break;    case Descending:      ras.cProfile->flow = TT_Flow_Down;      PTRACE7(( "New descending profile = %lx\n", (long)ras.cProfile ));      break;    default:      PTRACE0(( "Invalid profile direction in Raster:New_Profile !!\n" ));      ras.error = Raster_Err_Invalid;      return FAILURE;    }    ras.cProfile->start  = 0;    ras.cProfile->height = 0;    ras.cProfile->offset = ras.top;    ras.cProfile->link   = (PProfile)0;    ras.cProfile->next   = (PProfile)0;    if ( !ras.gProfile )      ras.gProfile = ras.cProfile;    ras.state = aState;    ras.fresh = TRUE;    ras.joint = FALSE;    return SUCCESS;  }/****************************************************************************//*                                                                          *//* Function:    End_Profile                                                 *//*                                                                          *//* Description: Finalizes the current Profile.                              *//*                                                                          *//* Input:       None                                                        *//*                                                                          *//* Returns:     SUCCESS on success.                                         *//*              FAILURE in case of overflow or incoherency.                 *//*                                                                          *//****************************************************************************/  static Bool  End_Profile( RAS_ARG )  {    Long      h;    PProfile  oldProfile;    h = ras.top - ras.cProfile->offset;    if ( h < 0 )    {      PTRACE0(( "Negative height encountered in End_Profile!\n" ));      ras.error = Raster_Err_Neg_Height;      return FAILURE;    }    if ( h > 0 )    {      PTRACE1(( "Ending profile %lx, start = %ld, height = %ld\n",                (long)ras.cProfile, ras.cProfile->start, h ));      oldProfile           = ras.cProfile;      ras.cProfile->height = h;      ras.cProfile         = (PProfile)ras.top;      ras.top             += AlignProfileSize;      ras.cProfile->height = 0;      ras.cProfile->offset = ras.top;      oldProfile->next     = ras.cProfile;      ras.num_Profs++;    }    if ( ras.top >= ras.maxBuff )    {      PTRACE1(( "overflow in End_Profile\n" ));      ras.error = Raster_Err_Overflow;      return FAILURE;    }    ras.joint = FALSE;    return SUCCESS;  }/****************************************************************************//*                                                                          *//* Function:    Insert_Y_Turn                                               *//*                                                                          *//* Description: Insert a salient into the sorted list placed on top         *//*              of the render pool                                          *//*                                                                          *//* Input:       New y scanline position                                     *//*                                                                          *//****************************************************************************/  static  Bool Insert_Y_Turn( RAS_ARGS  Int  y )  {    PStorage  y_turns;    Int       y2, n;    n       = ras.numTurns-1;    y_turns = ras.sizeBuff - ras.numTurns;    /* look for first y value that is <= */    while ( n >= 0 && y < y_turns[n] )      n--;    /* if it is <, simply insert it, ignore if == */    if ( n >= 0 && y > y_turns[n] )      while ( n >= 0 )      {        y2 = y_turns[n];        y_turns[n] = y;        y = y2;        n--;      }    if ( n < 0 )    {      if (ras.maxBuff <= ras.top)      {        ras.error = Raster_Err_Overflow;        return FAILURE;      }      ras.maxBuff--;      ras.numTurns++;      ras.sizeBuff[-ras.numTurns] = y;    }    return SUCCESS;  }/****************************************************************************//*                                                                          *//* Function:    Finalize_Profile_Table                                      *//*                                                                          *//* Description: Adjusts all links in the Profiles list.                     *//*                                                                          *//* Input:       None                                                        *//*                                                                          *//* Returns:     None.                                                       *//*                                                                          *//****************************************************************************/  static  Bool Finalize_Profile_Table( RAS_ARG )  {    Int       bottom, top;    UShort    n;    PProfile  p;    n = ras.num_Profs;    if ( n > 1 )    {      p = ras.fProfile;      while ( n > 0 )      {        if ( n > 1 )          p->link = (PProfile)( p->offset + p->height );        else          p->link = NULL;        switch ( p->flow )        {        case TT_Flow_Down:          bottom     = p->start - p->height+1;          top        = p->start;          p->start   = bottom;          p->offset += p->height-1;          break;        case TT_Flow_Up:        default:          bottom = p->start;          top    = p->start + p->height-1;        }        if ( Insert_Y_Turn( RAS_VARS  bottom ) ||             Insert_Y_Turn( RAS_VARS  top+1 )  )          return FAILURE;        p = p->link;        n--;      }    }    else      ras.fProfile = NULL;    return SUCCESS;  }/****************************************************************************//*                                                                          *//* Function:    Split_Bezier                                                *//*                                                                          *//* Description: Subdivides one Bezier arc into two joint                    *//*              sub-arcs in the Bezier stack.                               *//*                                                                          *//* Input:       None (subdivided bezier is taken from the top of the        *//*              stack).                                                     *//*                                                                          *//* Returns:     None.                                                       *//*                                                                          *//*                                                                          *//* Note:  This routine is the 'beef' of this component. It is  _the_        *//*        inner loop that should be optimized to hell to get the            *//*        best performance.                                                 *//*                                                                          *//****************************************************************************/  static void  Split_Bezier( TPoint*  base )  {    Long     a, b;    base[4].x = base[2].x;    b = base[1].x;    a = base[3].x = ( base[2].x + b ) / 2;    b = base[1].x = ( base[0].x + b ) / 2;    base[2].x = ( a + b ) / 2;    base[4].y = base[2].y;    b = base[1].y;    a = base[3].y = ( base[2].y + b ) / 2;    b = base[1].y = ( base[0].y + b ) / 2;    base[2].y = ( a + b ) / 2;    /* hand optimized.  gcc doesn't seem too good at common expression */    /* substitution and instruction scheduling ;-)                     */  }/****************************************************************************//*                                                                          *//* Function:    Push_Bezier                                                 *//*                                                                          *//* Description: Clears the Bezier stack and pushes a new arc on top of it.  *//*                                                                          *//* Input:       x1,y1 x2,y2 x3,y3  new Bezier arc                           *//*                                                                          *//* Returns:     None.                                                       *//*                                                                          *//****************************************************************************/  static void  Push_Bezier( RAS_ARGS Long  x1, Long  y1,                                     Long  x2, Long  y2,                                     Long  x3, Long  y3 )  {    ras.arc      = ras.arcs;    ras.arc[2].x = x1; ras.arc[2].y = y1;    ras.arc[1].x = x2; ras.arc[1].y = y2;    ras.arc[0].x = x3; ras.arc[0].y = y3;  }/****************************************************************************//*                                                                          *//* Function:    Line_Up                                                     *//*                                                                          *//* Description: Computes the x-coordinates of an ascending line segment     *//*              and stores them in the render pool.                         *//*                                                                          *//* Input:       x1,y1,x2,y2  Segment start (x1,y1) and end (x2,y2) points   *//*                                                                          *//* Returns:     SUCCESS on success.                                         *//*              FAILURE on Render Pool overflow.                            *//*                                                                          *//****************************************************************************/  static Bool  Line_Up( RAS_ARGS Long  x1, Long  y1,                                 Long  x2, Long  y2,                                 Long  miny, Long  maxy )  {    Long  Dx, Dy;    Int   e1, e2, f1, f2, size;     /* XXX: is `Short' sufficient? */    Long  Ix, Rx, Ax;    PStorage  top;    Dx = x2 - x1;    Dy = y2 - y1;    if ( Dy <= 0 || y2 < miny || y1 > maxy )      return SUCCESS;    if ( y1 < miny )    {      /* Take care : miny-y1 can be a very large value, we use     */      /*             a slow MulDiv function to avoid clipping bugs */      x1 += SMulDiv( Dx, miny - y1, Dy );      e1  = TRUNC( miny );      f1  = 0;    }    else    {      e1 = TRUNC( y1 );      f1 = FRAC( y1 );    }    if ( y2 > maxy )    {      /* x2 += FMulDiv( Dx, maxy - y2, Dy );  UNNECESSARY */      e2  = TRUNC( maxy );      f2  = 0;    }    else    {      e2 = TRUNC( y2 );      f2 = FRAC( y2 );    }    if ( f1 > 0 )    {      if ( e1 == e2 ) return SUCCESS;      else      {        x1 += FMulDiv( Dx, ras.precision - f1, Dy );        e1 += 1;      }    }    else      if ( ras.joint )      {        ras.top--;        ras.joint = FALSE;      }    ras.joint = ( f2 == 0 );    if ( ras.fresh )    {      ras.cProfile->start = e1;      ras.fresh           = FALSE;    }    size = e2 - e1 + 1;    if ( ras.top + size >= ras.maxBuff )    {      ras.error = Raster_Err_Overflow;      return FAILURE;    }    if ( Dx > 0 )    {      Ix = (ras.precision*Dx) / Dy;      Rx = (ras.precision*Dx) % Dy;      Dx = 1;    }    else    {      Ix = -( (ras.precision*-Dx) / Dy );      Rx =    (ras.precision*-Dx) % Dy;      Dx = -1;    }    Ax  = -Dy;    top = ras.top;    while ( size > 0 )    {      *top++ = x1;      DEBUG_PSET;      x1 += Ix;      Ax += Rx;      if ( Ax >= 0 )      {        Ax -= Dy;        x1 += Dx;      }      size--;    }    ras.top = top;    return SUCCESS;  }  static Bool  Line_Down( RAS_ARGS Long  x1, Long  y1,                                   Long  x2, Long  y2,                                   Long  miny, Long  maxy )  {    Bool result, fresh;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -