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

📄 ftraster.c

📁 Qt/Embedded是一个多平台的C++图形用户界面应用程序框架
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* <Input>                                                               */  /*    x1   :: The start x coordinate.                                    */  /*    y1   :: The start y coordinate.                                    */  /*    x2   :: The end x coordinate.                                      */  /*    y2   :: The end y coordinate.                                      */  /*    miny :: The minimum vertical grid coordinate.                      */  /*    maxy :: The maximum vertical grid coordinate.                      */  /*                                                                       */  /* <Return>                                                              */  /*    SUCCESS or FAILURE.                                                */  /*                                                                       */  static  TResult  Line_Down( RAS_ARG_ TPos  x1,   TPos  y1,                               TPos  x2,   TPos  y2,                               TPos  miny, TPos  maxy )  {    TResult  result, fresh;    /* simply invert the coordinates and call Line_Up */    fresh  = ras.fresh;    result = Line_Up( RAS_VAR_ x1, -y1, x2, -y2, -maxy, -miny );    /* if this was a fresh profile, invert the recorded start position */    if ( fresh && !ras.fresh )      ras.cur_prof->start = -ras.cur_prof->start;    return result;  } /* A function type describing the functions used to split bezier arcs */  typedef  void  (*TSplitter)( TPoint*  base );#ifdef FT_DYNAMIC_BEZIER_STEPS  static  TPos  Dynamic_Bezier_Threshold( RAS_ARG_ int degree, TPoint*  arc )  {    TPos    min_x,  max_x,  min_y, max_y, A, B;    TPos    wide_x, wide_y, threshold;    TPoint* cur   = arc;    TPoint* limit = cur + degree;    /* first of all, set the threshold to the maximum x or y extent */    min_x = max_x = arc[0].x;    min_y = max_y = arc[0].y;    cur++;    for ( ; cur < limit; cur++ )    {      TPos  x = cur->x;      TPos  y = cur->y;      if ( x < min_x ) min_x = x;      if ( x > max_x ) max_x = x;      if ( y < min_y ) min_y = y;      if ( y > max_y ) max_y = y;    }    wide_x = (max_x - min_x) << 4;    wide_y = (max_y - min_y) << 4;    threshold = wide_x;    if (threshold < wide_y) threshold = wide_y;    /* now compute the second and third order error values */        wide_x = arc[0].x + arc[1].x - arc[2].x*2;    wide_y = arc[0].y + arc[1].y - arc[2].y*2;    if (wide_x < 0) wide_x = -wide_x;    if (wide_y < 0) wide_y = -wide_y;    A = wide_x; if ( A < wide_y ) A = wide_y;    if (degree >= 3)    {      wide_x = arc[3].x - arc[0].x + 3*(arc[2].x - arc[3].x);      wide_y = arc[3].y - arc[0].y + 3*(arc[2].y - arc[3].y);      if (wide_x < 0) wide_x = -wide_x;      if (wide_y < 0) wide_y = -wide_y;      B = wide_x; if ( B < wide_y ) B = wide_y;    }    else      B = 0;    while ( A > 0 || B > 0 )    {      threshold >>= 1;      A         >>= 2;      B         >>= 3;    }    if (threshold < PRECISION_STEP)      threshold = PRECISION_STEP;    return threshold;  }#endif  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    Bezier_Up                                                          */  /*                                                                       */  /* <Description>                                                         */  /*    Computes the scan-line intersections of an ascending second-order  */  /*    Bezier arc and stores them in the render pool.  The arc is taken   */  /*    from the top of the stack.                                         */  /*                                                                       */  /* <Input>                                                               */  /*    miny :: The minimum vertical grid coordinate.                      */  /*    maxy :: The maximum vertical grid coordinate.                      */  /*                                                                       */  /* <Return>                                                              */  /*    SUCCESS or FAILURE.                                                */  /*                                                                       */  static  TResult  Bezier_Up( RAS_ARG_ int        degree,                               TSplitter  splitter,                               TPos       miny,                               TPos       maxy )  {    TPos  y1, y2, e, e2, e0, threshold;    int   f1;    TPoint*  arc;    TPoint*  start_arc;    PPos top;    arc = ras.arc;    y1  = arc[degree].y;    y2  = arc[0].y;    top = ras.cursor;    if ( y2 < miny || y1 > maxy )      goto Fin;    e2 = FLOOR( y2 );  /* integer end y */    if ( e2 > maxy )      e2 = FLOOR(maxy);    e0 = CEILING(miny);    if ( y1 < miny )    {      e = e0;        /* integer start y == current scanline */    }    else    {      e  = CEILING( y1 );   /* integer start y == current scanline */      f1 = FRAC( y1 );      /* fractional shift of start y         */      e0 = e;               /* first integer scanline to be pushed */      if ( f1 == 0 )        /* do we start on an integer scanline? */      {        if ( ras.joint )        {          top--;          ras.joint = FALSE;        }        *top++ = arc[degree].x;  /* write directly start position */        DEBUG_PSET;        e += PRECISION; /* go to next scanline */      }    }    /* record start position if necessary */    if ( ras.fresh )    {      ras.cur_prof->start = TRUNC( e0 );      ras.fresh = FALSE;    }    /* exit if the current scanline is already above the max scanline */    if ( e2 < e )      goto Fin;    /* check for overflow */    if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.pool_limit )    {      ras.cursor = top;      ras.error  = ErrRaster_Overflow;      return FAILURE;    }#ifdef FT_DYNAMIC_BEZIER_STEPS    /* compute dynamic bezier step threshold */    threshold = Dynamic_Bezier_Threshold( RAS_VAR_ degree, arc );#else    threshold = PRECISION_STEP;#endif    start_arc = arc;    /* loop while there is still an arc on the bezier stack */    /* and the current scan line is below y max == e2       */    while ( arc >= start_arc && e <= e2 )    {      ras.joint = FALSE;      y2 = arc[0].y;  /* final y of the top-most arc */      if ( y2 > e )   /* the arc intercepts the current scanline */      {        y1 = arc[degree].y;  /* start y of top-most arc */        if ( y2 >= e + PRECISION || y2 - y1 >= threshold )        {          /* if the arc's height is too great, split it */          splitter( arc );          arc += degree;        }        else        {          /* otherwise, approximate it as a segment and compute */          /* its intersection with the current scanline         */          *top++ = arc[degree].x +                   FMulDiv( arc[0].x-arc[degree].x,                            e  - y1,                            y2 - y1 );          DEBUG_PSET;          arc -= degree;         /* pop the arc         */          e   += PRECISION;  /* go to next scanline */        }      }      else      {        if ( y2 == e )        /* if the arc falls on the scanline */        {                     /* record its _joint_ intersection  */          ras.joint  = TRUE;          *top++     = arc[0].x;          DEBUG_PSET;          e += PRECISION; /* go to next scanline */        }        arc -= degree;        /* pop the arc */      }    }  Fin:    ras.cursor = top;    ras.arc   -= degree;    return SUCCESS;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    Bezier_Down                                                        */  /*                                                                       */  /* <Description>                                                         */  /*    Computes the scan-line intersections of a descending second-order  */  /*    Bezier arc and stores them in the render pool.  The arc is taken   */  /*    from the top of the stack.                                         */  /*                                                                       */  /* <Input>                                                               */  /*    miny :: The minimum vertical grid coordinate.                      */  /*    maxy :: The maximum vertical grid coordinate.                      */  /*                                                                       */  /* <Return>                                                              */  /*    SUCCESS or FAILURE.                                                */  /*                                                                       */  static  TResult  Bezier_Down( RAS_ARG_ int        degree,                                 TSplitter  splitter,                                 TPos       miny,                                 TPos       maxy )  {    TPoint*  arc = ras.arc;    TResult  result, fresh;    arc[0].y = -arc[0].y;    arc[1].y = -arc[1].y;    arc[2].y = -arc[2].y;    if (degree > 2)      arc[3].y = -arc[3].y;    fresh = ras.fresh;    result = Bezier_Up( RAS_VAR_ degree, splitter, -maxy, -miny );    if ( fresh && !ras.fresh )      ras.cur_prof->start = -ras.cur_prof->start;    arc[0].y = -arc[0].y;    return result;  }#ifdef FT_RASTER_CONIC_BEZIERS  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    Split_Conic                                                        */  /*                                                                       */  /* <Description>                                                         */  /*    Subdivides one second-order Bezier arc into two joint sub-arcs in  */  /*    the Bezier stack.                                                  */  /*                                                                       */  /* <Note>                                                                */  /*    This routine is the `beef' of the component.  It is one of _the_   */  /*    inner loops that should be optimized like hell to get the best     */  /*    performance.                                           

⌨️ 快捷键说明

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