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

📄 ftraster.c

📁 qt-embedded-2.3.8.tar.gz源码
💻 C
📖 第 1 页 / 共 5 页
字号:
  /*   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 : Descending;        /* detect a change of direction */        if ( ras.state != state_bez )        {          if ( ras.state != Unknown   &&               End_Profile( RAS_VAR ) )            goto Fail;          if ( New_Profile( RAS_VARS state_bez ) )            goto Fail;        }        /* compute intersections */        if ( state_bez == Ascending )        {          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 arays 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;    char        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! */    if ( tag == FT_Curve_Tag_Cubic )      goto Invalid_Outline;    /* check first point to determine origin */    if ( tag == FT_Curve_Tag_Conic )    {      /* first point is conic control.  Yes, this happens. */      if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_Curve_Tag_On )      {        /* start at last point if it is on the curve */        v_start = v_last;        limit--;      }      else      {        /* if both first and last points are conic,         */        /* start at their middle and record its position    */        /* for closure                                      */        v_start.x = ( v_start.x + v_last.x ) / 2;        v_start.y = ( v_start.y + v_last.y ) / 2;        v_last = v_start;      }      point--;      tags--;    }    ras.lastX = v_start.x;    ras.lastY = v_start.y;    while ( point < limit )    {      point++;      tags++;      tag = FT_CURVE_TAG( tags[0] );      switch ( tag )      {      case FT_Curve_Tag_On:  /* emit a single line_to */        {          Long  x, y;          x = SCALED( point->x );          y = SCALED( point->y );          if ( flipped )            SWAP_( x, y );          if ( Line_To( RAS_VARS x, y ) )            goto Fail;          continue;        }      case FT_Curve_Tag_Conic:  /* consume conic arcs */        v_control.x = SCALED( point[0].x );        v_control.y = SCALED( point[0].y );        if ( flipped )          SWAP_( v_control.x, v_control.y );      Do_Conic:        if ( point < limit )        {          FT_Vector  v_middle;          Long       x, y;          point++;          tags++;          tag = FT_CURVE_TAG( tags[0] );          x = SCALED( point[0].x );          y = SCALED( point[0].y );          if ( flipped )            SWAP_( x, y );          if ( tag == FT_Curve_Tag_On )          {            if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) )              goto Fail;            continue;          }          if ( tag != FT_Curve_Tag_Conic )            goto Invalid_Outline;          v_middle.x = ( v_control.x + x ) / 2;          v_middle.y = ( v_control.y + y ) / 2;          if ( Conic_To( RAS_VARS v_control.x, v_control.y,                                  v_middle.x,  v_middle.y ) )            goto Fail;          v_control.x = x;          v_control.y = y;          goto Do_Conic;        }        if ( Conic_To( RAS_VARS v_control.x, v_control.y,                                v_start.x,   v_start.y ) )          goto Fail;        goto Close;      default:  /* FT_Curve_Tag_Cubic */        {          Long  x1, y1, x2, y2, x3, y3;          if ( point + 1 > limit                             ||               FT_CURVE_TAG( tags[1] ) != FT_Curve_Tag_Cubic )            goto Invalid_Outline;          point += 2;          tags  += 2;          x1 = SCALED( point[-2].x );          y1 = SCALED( point[-2].y );          x2 = SCALED( point[-1].x );          y2 = SCALED( point[-1].y );          x3 = SCALED( point[ 0].x );          y3 = SCALED( point[ 0].y );          if ( flipped )          {            SWAP_( x1, y1 );            SWAP_( x2, y2 );            SWAP_( x3, y3 );          }          if ( point <= limit )          {            if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) )              goto Fail;            continue;          }          if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) )            goto Fail;          goto Close;        }      }    }    /* close the contour with a line segment */    if ( Line_To( RAS_VARS v_start.x, v_start.y ) )      goto Fail;  Close:    return SUCCESS;  Invalid_Outline:    ras.error = Raster_Err_Invalid;  Fail:    return FAILURE;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    Convert_Glyph                                                      */  /*                                                                       */  /* <Description>                                                         */  /*    Converts a glyph into a series of segments and arcs and makes a    */  /*    profiles list with them.                                           */  /*                                                                       */  /* <Input>                                                      

⌨️ 快捷键说明

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