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

📄 ftraster.c

📁 这是一个开放源代码的与WINNT/WIN2K/WIN2003兼容的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
      ;
    }

    /* Then compute the lines */

    switch ( ras.state )
    {
    case Ascending_State:
      if ( Line_Up( RAS_VARS ras.lastX, ras.lastY,
                    x, y, ras.minY, ras.maxY ) )
        return FAILURE;
      break;

    case Descending_State:
      if ( Line_Down( RAS_VARS ras.lastX, ras.lastY,
                      x, y, ras.minY, ras.maxY ) )
        return FAILURE;
      break;

    default:
      ;
    }

    ras.lastX = x;
    ras.lastY = y;

    return SUCCESS;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    Conic_To                                                           */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Injects a new conic arc and adjusts the profile list.              */
  /*                                                                       */
  /* <Input>                                                               */
  /*   cx :: The x-coordinate of the arc's new control point.              */
  /*                                                                       */
  /*   cy :: The y-coordinate of the arc's new control point.              */
  /*                                                                       */
  /*   x  :: The x-coordinate of the arc's end point (its start point is   */
  /*         stored in `lastX').                                           */
  /*                                                                       */
  /*   y  :: The y-coordinate of the arc's end point (its start point is   */
  /*         stored in `lastY').                                           */
  /*                                                                       */
  /* <Return>                                                              */
  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */
  /*   profile.                                                            */
  /*                                                                       */
  static Bool
  Conic_To( RAS_ARGS Long  cx,
                     Long  cy,
                     Long  x,
                     Long  y )
  {
    Long     y1, y2, y3, x3, ymin, ymax;
    TStates  state_bez;


    ras.arc      = ras.arcs;
    ras.arc[2].x = ras.lastX;
    ras.arc[2].y = ras.lastY;
    ras.arc[1].x = cx; ras.arc[1].y = cy;
    ras.arc[0].x = x;  ras.arc[0].y = y;

    do
    {
      y1 = ras.arc[2].y;
      y2 = ras.arc[1].y;
      y3 = ras.arc[0].y;
      x3 = ras.arc[0].x;

      /* first, categorize the Bezier arc */

      if ( y1 <= y3 )
      {
        ymin = y1;
        ymax = y3;
      }
      else
      {
        ymin = y3;
        ymax = y1;
      }

      if ( y2 < ymin || y2 > ymax )
      {
        /* this arc has no given direction, split it! */
        Split_Conic( ras.arc );
        ras.arc += 2;
      }
      else if ( y1 == y3 )
      {
        /* this arc is flat, ignore it and pop it from the Bezier stack */
        ras.arc -= 2;
      }
      else
      {
        /* the arc is y-monotonous, either ascending or descending */
        /* detect a change of direction                            */
        state_bez = y1 < y3 ? Ascending_State : Descending_State;
        if ( ras.state != state_bez )
        {
          /* finalize current profile if any */
          if ( ras.state != Unknown_State   &&
               End_Profile( RAS_VAR ) )
            goto Fail;

          /* create a new profile */
          if ( New_Profile( RAS_VARS state_bez ) )
            goto Fail;
        }

        /* now call the appropriate routine */
        if ( state_bez == Ascending_State )
        {
          if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
            goto Fail;
        }
        else
          if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) )
            goto Fail;
      }

    } while ( ras.arc >= ras.arcs );

    ras.lastX = x3;
    ras.lastY = y3;

    return SUCCESS;

  Fail:
    return FAILURE;
  }


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    Cubic_To                                                           */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Injects a new cubic arc and adjusts the profile list.              */
  /*                                                                       */
  /* <Input>                                                               */
  /*   cx1 :: The x-coordinate of the arc's first new control point.       */
  /*                                                                       */
  /*   cy1 :: The y-coordinate of the arc's first new control point.       */
  /*                                                                       */
  /*   cx2 :: The x-coordinate of the arc's second new control point.      */
  /*                                                                       */
  /*   cy2 :: The y-coordinate of the arc's second new control point.      */
  /*                                                                       */
  /*   x   :: The x-coordinate of the arc's end point (its start point is  */
  /*          stored in `lastX').                                          */
  /*                                                                       */
  /*   y   :: The y-coordinate of the arc's end point (its start point is  */
  /*          stored in `lastY').                                          */
  /*                                                                       */
  /* <Return>                                                              */
  /*   SUCCESS on success, FAILURE on render pool overflow or incorrect    */
  /*   profile.                                                            */
  /*                                                                       */
  static Bool
  Cubic_To( RAS_ARGS Long  cx1,
                     Long  cy1,
                     Long  cx2,
                     Long  cy2,
                     Long  x,
                     Long  y )
  {
    Long     y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2;
    TStates  state_bez;


    ras.arc      = ras.arcs;
    ras.arc[3].x = ras.lastX;
    ras.arc[3].y = ras.lastY;
    ras.arc[2].x = cx1; ras.arc[2].y = cy1;
    ras.arc[1].x = cx2; ras.arc[1].y = cy2;
    ras.arc[0].x = x;   ras.arc[0].y = y;

    do
    {
      y1 = ras.arc[3].y;
      y2 = ras.arc[2].y;
      y3 = ras.arc[1].y;
      y4 = ras.arc[0].y;
      x4 = ras.arc[0].x;

      /* first, categorize the Bezier arc */

      if ( y1 <= y4 )
      {
        ymin1 = y1;
        ymax1 = y4;
      }
      else
      {
        ymin1 = y4;
        ymax1 = y1;
      }

      if ( y2 <= y3 )
      {
        ymin2 = y2;
        ymax2 = y3;
      }
      else
      {
        ymin2 = y3;
        ymax2 = y2;
      }

      if ( ymin2 < ymin1 || ymax2 > ymax1 )
      {
        /* this arc has no given direction, split it! */
        Split_Cubic( ras.arc );
        ras.arc += 3;
      }
      else if ( y1 == y4 )
      {
        /* this arc is flat, ignore it and pop it from the Bezier stack */
        ras.arc -= 3;
      }
      else
      {
        state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State;

        /* detect a change of direction */
        if ( ras.state != state_bez )
        {
          if ( ras.state != Unknown_State   &&
               End_Profile( RAS_VAR ) )
            goto Fail;

          if ( New_Profile( RAS_VARS state_bez ) )
            goto Fail;
        }

        /* compute intersections */
        if ( state_bez == Ascending_State )
        {
          if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
            goto Fail;
        }
        else
          if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) )
            goto Fail;
      }

    } while ( ras.arc >= ras.arcs );

    ras.lastX = x4;
    ras.lastY = y4;

    return SUCCESS;

  Fail:
    return FAILURE;
  }


#undef  SWAP_
#define SWAP_( x, y )  do                \
                       {                 \
                         Long  swap = x; \
                                         \
                                         \
                         x = y;          \
                         y = swap;       \
                       } while ( 0 )


  /*************************************************************************/
  /*                                                                       */
  /* <Function>                                                            */
  /*    Decompose_Curve                                                    */
  /*                                                                       */
  /* <Description>                                                         */
  /*    Scans the outline arrays in order to emit individual segments and  */
  /*    Beziers by calling Line_To() and Bezier_To().  It handles all      */
  /*    weird cases, like when the first point is off the curve, or when   */
  /*    there are simply no `on' points in the contour!                    */
  /*                                                                       */
  /* <Input>                                                               */
  /*    first   :: The index of the first point in the contour.            */
  /*                                                                       */
  /*    last    :: The index of the last point in the contour.             */
  /*                                                                       */
  /*    flipped :: If set, flip the direction of the curve.                */
  /*                                                                       */
  /* <Return>                                                              */
  /*    SUCCESS on success, FAILURE on error.                              */
  /*                                                                       */
  static Bool
  Decompose_Curve( RAS_ARGS UShort  first,
                            UShort  last,
                            int     flipped )
  {
    FT_Vector   v_last;
    FT_Vector   v_control;
    FT_Vector   v_start;

    FT_Vector*  points;
    FT_Vector*  point;
    FT_Vector*  limit;
    char*       tags;

    unsigned    tag;       /* current point's state           */


    points = ras.outline.points;
    limit  = points + last;

    v_start.x = SCALED( points[first].x );
    v_start.y = SCALED( points[first].y );
    v_last.x  = SCALED( points[last].x );
    v_last.y  = SCALED( points[last].y );

    if ( flipped )
    {
      SWAP_( v_start.x, v_start.y );
      SWAP_( v_last.x, v_last.y );
    }

    v_control = v_start;

    point = points + first;
    tags  = ras.outline.tags  + first;
    tag   = FT_CURVE_TAG( tags[0] );

    /* A contour cannot start with a cubic control point! *

⌨️ 快捷键说明

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