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

📄 ttraster.c

📁 神龙卡开发原代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        ras.lastX = (ras.lastX + x_last)/2;        ras.lastY = (ras.lastY + y_last)/2;        x_last = ras.lastX;        y_last = ras.lastY;      }    }    /* now process each contour point individually */    while ( index < last )    {      index++;      x = SCALED( ras.coords[index].x );      y = SCALED( ras.coords[index].y );      if ( flipped ) SWAP_( x, y );      if ( on_curve )      {        /* the previous point was on the curve */        on_curve = ( ras.flags[index] & 1 );        if ( on_curve )        {          /* two successive on points => emit segment */          if ( Line_To( RAS_VARS  x, y ) ) return FAILURE;        }        else        {          /* else, keep current control point for next bezier */          cx = x;          cy = y;        }      }      else      {        /* the previous point was off the curve */        on_curve = ( ras.flags[index] & 1 );        if ( on_curve )        {          /* reaching an `on' point */          if ( Bezier_To( RAS_VARS  x, y, cx, cy ) ) return FAILURE;        }        else        {          /* two successive `off' points => create middle point */          mx = ( cx + x ) / 2;          my = ( cy + y ) / 2;          if ( Bezier_To( RAS_VARS  mx, my, cx, cy ) ) return FAILURE;          cx = x;          cy = y;        }      }    }    /* end of contour, close curve cleanly */    if ( ras.flags[first] & 1 )    {      if ( on_curve )        return Line_To( RAS_VARS  x_first, y_first );      else        return Bezier_To( RAS_VARS  x_first, y_first, cx, cy );    }    else      if ( !on_curve )        return Bezier_To( RAS_VARS  x_last, y_last, cx, cy );    return SUCCESS;  }/****************************************************************************//*                                                                          *//* Function:    Convert_Glyph                                               *//*                                                                          *//* Description: Converts a glyph into a series of segments and arcs         *//*              and makes a Profiles list with them.                        *//*                                                                          *//* Input:       _xCoord, _yCoord : coordinates tables.                      *//*                                                                          *//*              Uses the 'Flag' table too.                                  *//*                                                                          *//* Returns:     SUCCESS on success.                                         *//*              FAILURE if any error was encountered during rendering.      *//*                                                                          *//****************************************************************************/  static Bool  Convert_Glyph( RAS_ARGS int  flipped )  {    Short     i;    UShort    start;    PProfile  lastProfile;    ras.fProfile = NULL;    ras.joint    = FALSE;    ras.fresh    = FALSE;    ras.maxBuff  = ras.sizeBuff - AlignProfileSize;    ras.numTurns = 0;    ras.cProfile         = (PProfile)ras.top;    ras.cProfile->offset = ras.top;    ras.num_Profs        = 0;    start = 0;    for ( i = 0; i < ras.nContours; i++ )    {      ras.state    = Unknown;      ras.gProfile = NULL;      if ( Decompose_Curve( RAS_VARS  start, ras.outs[i], flipped ) )        return FAILURE;      start = ras.outs[i] + 1;      /* We must now see if the extreme arcs join or not */      if ( ( FRAC( ras.lastY ) == 0 &&             ras.lastY >= ras.minY      &&             ras.lastY <= ras.maxY ) )        if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow )          ras.top--;        /* Note that ras.gProfile can be nil if the contour was too small */        /* to be drawn.                                                   */      lastProfile = ras.cProfile;      if ( End_Profile( RAS_VAR ) ) return FAILURE;      /* close the 'next profile in contour' linked list */      if ( ras.gProfile )        lastProfile->next = ras.gProfile;    }    if (Finalize_Profile_Table( RAS_VAR ))      return FAILURE;    return (ras.top < ras.maxBuff ? SUCCESS : FAILURE );  }/************************************************//*                                              *//*  Init_Linked                                 *//*                                              *//*    Inits an empty linked list.               *//*                                              *//************************************************/  static void  Init_Linked( TProfileList*  l )  {    *l = NULL;  }/************************************************//*                                              *//*  InsNew :                                    *//*                                              *//*    Inserts a new Profile in a linked list.   *//*                                              *//************************************************/  static void  InsNew( PProfileList  list,                       PProfile      profile )  {    PProfile  *old, current;    Long       x;    old     = list;    current = *old;    x       = profile->X;    while ( current )    {      if ( x < current->X )        break;      old     = &current->link;      current = *old;    }    profile->link = current;    *old          = profile;  }/*************************************************//*                                               *//*  DelOld :                                     *//*                                               *//*    Removes an old Profile from a linked list. *//*                                               *//*************************************************/  static void  DelOld( PProfileList  list,                       PProfile      profile )  {    PProfile  *old, current;    old     = list;    current = *old;    while ( current )    {      if ( current == profile )      {        *old = current->link;        return;      }      old     = &current->link;      current = *old;    }    /* we should never get there, unless the Profile was not part of */    /* the list.                                                     */  }/************************************************//*                                              *//*  Update :                                    *//*                                              *//*    Update all X offsets of a drawing list    *//*                                              *//************************************************/  static void  Update( PProfile  first )  {    PProfile  current = first;    while ( current )    {      current->X       = *current->offset;      current->offset += current->flow;      current->height--;      current = current->link;    }  }/************************************************//*                                              *//*  Sort :                                      *//*                                              *//*    Sorts a trace list.  In 95%, the list     *//*    is already sorted.  We need an algorithm  *//*    which is fast in this case.  Bubble sort  *//*    is enough and simple.                     *//*                                              *//************************************************/  static void  Sort( PProfileList  list )  {    PProfile  *old, current, next;    /* First, set the new X coordinate of each profile */    Update( *list );    /* Then sort them */    old     = list;    current = *old;    if ( !current )      return;    next = current->link;    while ( next )    {      if ( current->X <= next->X )      {        old     = &current->link;        current = *old;        if ( !current )          return;      }      else      {        *old          = next;        current->link = next->link;        next->link    = current;        old     = list;        current = *old;      }      next = current->link;    }  }/***********************************************************************//*                                                                     *//*  Vertical Sweep Procedure Set :                                     *//*                                                                     *//*  These three routines are used during the vertical black/white      *//*  sweep phase by the generic Draw_Sweep() function.                  *//*                                                                     *//***********************************************************************/  static void  Vertical_Sweep_Init( RAS_ARGS Short*  min, Short*  max )  {    switch ( ras.target.flow )    {    case TT_Flow_Up:      ras.traceOfs  = *min * ras.target.cols;      ras.traceIncr = ras.target.cols;      break;    default:      ras.traceOfs  = ( ras.target.rows - 1 - *min ) * ras.target.cols;      ras.traceIncr = -ras.target.cols;    }    ras.gray_min_x = 0;    ras.gray_max_x = 0;  }  static void  Vertical_Sweep_Span( RAS_ARGS Short       y,                                             TT_F26Dot6  x1,                                             TT_F26Dot6  x2,                                             PProfile    left,                                             PProfile    right )  {    Long   e1, e2;    Short  c1, c2;    Short  f1, f2;    Byte*  target;    /* Drop-out control */    e1 = TRUNC( CEILING( x1 ) );    if ( x2-x1-ras.precision <= ras.precision_jitter )      e2 = e1;    else      e2 = TRUNC( FLOOR( x2 ) );    if ( e2 >= 0 && e1 < ras.bWidth )    {      if ( e1 < 0 )           e1 = 0;      if ( e2 >= ras.bWidth ) e2 = ras.bWidth-1;      c1 = (Short)(e1 >> 3);      c2 = (Short)(e2 >> 3);      f1 = e1 & 7;      f2 = e2 & 7;      if ( ras.gray_min_x > c1 ) ras.gray_min_x = c1;      if ( ras.gray_max_x < c2 ) ras.gray_max_x = c2;      target = ras.bTarget + ras.traceOfs + c1;      if ( c1 != c2 )      {        *target |= LMask[f1];        if ( c2 > c1 + 1 )          MEM_Set( target + 1, 0xFF, c2 - c1 - 1 );        target[c2 - c1] |= RMask[f2];      }      else        *target |= ( LMask[f1] & RMask[f2] );    }  }  static void  Vertical_Sweep_Drop( RAS_ARGS Short       y,                                             TT_F26Dot6  x1,                                             TT_F26Dot6  x2,                                             PProfile    left,                                             PProfile    right )  {    Long   e1, e2;    Short  c1, f1;    /* Drop-out control */    e1 = CEILING( x1 );    e2 = FLOOR  ( x2 );    if ( e1 > e2 )    {      if ( e1 == e2 + ras.precision )      {        switch ( ras.dropOutControl )        {        case 1:          e1 = e2;          break;        case 4:          e1 = CEILING( (x1 + x2 + 1) / 2 );          break;        case 2:        case 5:          /* Drop-out Control Rule #4 */          /* The spec is not very clear regarding rule #4.  It      */          /* presents a method that is way too costly to implement  */          /* while the general idea seems to get rid of 'stubs'.    */          /*                                                        */          /* Here, we only get rid of stubs recognized when:        */          /*                                                        */          /*  upper stub:                                           */          /*                                                        */          /*   - P_Left and P_Right are in the same contour         */          /*   - P_Right is the successor of P_Left in that contour */          /*   - y is the top of P_Left and P_Right                 */          /*                                                        */          /*  lower stub:                                           */          /*                                                        */          /*   - P_Left and P_Right are in the same contour         */

⌨️ 快捷键说明

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