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

📄 ftgrays.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 4 页
字号:
      gray_render_line( RAS_VAR_ mid_x, mid_y );      gray_render_line( RAS_VAR_ to_x, to_y );      return;    }    arc      = ras.bez_stack;    arc[0].x = UPSCALE( to->x );    arc[0].y = UPSCALE( to->y );    arc[1].x = UPSCALE( control2->x );    arc[1].y = UPSCALE( control2->y );    arc[2].x = UPSCALE( control1->x );    arc[2].y = UPSCALE( control1->y );    arc[3].x = ras.x;    arc[3].y = ras.y;    levels    = ras.lev_stack;    top       = 0;    levels[0] = level;    while ( top >= 0 )    {      level = levels[top];      if ( level > 1 )      {        /* check that the arc crosses the current band */        TPos  min, max, y;        min = max = arc[0].y;        y = arc[1].y;        if ( y < min ) min = y;        if ( y > max ) max = y;        y = arc[2].y;        if ( y < min ) min = y;        if ( y > max ) max = y;        y = arc[3].y;        if ( y < min ) min = y;        if ( y > max ) max = y;        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )          goto Draw;        gray_split_cubic( arc );        arc += 3;        top ++;        levels[top] = levels[top - 1] = level - 1;        continue;      }    Draw:      {        TPos  to_x, to_y, mid_x, mid_y;        to_x  = arc[0].x;        to_y  = arc[0].y;        mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8;        mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8;        gray_render_line( RAS_VAR_ mid_x, mid_y );        gray_render_line( RAS_VAR_ to_x, to_y );        top --;        arc -= 3;      }    }    return;  }  static int  gray_move_to( const FT_Vector*  to,                PWorker           worker )  {    TPos  x, y;    /* record current cell, if any */    gray_record_cell( worker );    /* start to a new position */    x = UPSCALE( to->x );    y = UPSCALE( to->y );    gray_start_cell( worker, TRUNC( x ), TRUNC( y ) );    worker->x = x;    worker->y = y;    return 0;  }  static int  gray_line_to( const FT_Vector*  to,                PWorker           worker )  {    gray_render_line( worker, UPSCALE( to->x ), UPSCALE( to->y ) );    return 0;  }  static int  gray_conic_to( const FT_Vector*  control,                 const FT_Vector*  to,                 PWorker           worker )  {    gray_render_conic( worker, control, to );    return 0;  }  static int  gray_cubic_to( const FT_Vector*  control1,                 const FT_Vector*  control2,                 const FT_Vector*  to,                 PWorker           worker )  {    gray_render_cubic( worker, control1, control2, to );    return 0;  }  static void  gray_render_span( int             y,                    int             count,                    const FT_Span*  spans,                    PWorker         worker )  {    unsigned char*  p;    FT_Bitmap*      map = &worker->target;    /* first of all, compute the scanline offset */    p = (unsigned char*)map->buffer - y * map->pitch;    if ( map->pitch >= 0 )      p += ( map->rows - 1 ) * map->pitch;    for ( ; count > 0; count--, spans++ )    {      unsigned char  coverage = spans->coverage;      if ( coverage )      {        /* For small-spans it is faster to do it by ourselves than         * calling `memset'.  This is mainly due to the cost of the         * function call.         */        if ( spans->len >= 8 )          FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );        else        {          unsigned char*  q = p + spans->x;          switch ( spans->len )          {          case 7: *q++ = (unsigned char)coverage;          case 6: *q++ = (unsigned char)coverage;          case 5: *q++ = (unsigned char)coverage;          case 4: *q++ = (unsigned char)coverage;          case 3: *q++ = (unsigned char)coverage;          case 2: *q++ = (unsigned char)coverage;          case 1: *q   = (unsigned char)coverage;          default:            ;          }        }      }    }  }  static void  gray_hline( RAS_ARG_ TCoord  x,                       TCoord  y,                       TPos    area,                       int     acount )  {    FT_Span*  span;    int       count;    int       coverage;    /* compute the coverage line's coverage, depending on the    */    /* outline fill rule                                         */    /*                                                           */    /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */    /*                                                           */    coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) );                                                    /* use range 0..256 */    if ( coverage < 0 )      coverage = -coverage;    if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )    {      coverage &= 511;      if ( coverage > 256 )        coverage = 512 - coverage;      else if ( coverage == 256 )        coverage = 255;    }    else    {      /* normal non-zero winding rule */      if ( coverage >= 256 )        coverage = 255;    }    y += (TCoord)ras.min_ey;    x += (TCoord)ras.min_ex;    if ( coverage )    {      /* see whether we can add this span to the current list */      count = ras.num_gray_spans;      span  = ras.gray_spans + count - 1;      if ( count > 0                          &&           ras.span_y == y                    &&           (int)span->x + span->len == (int)x &&           span->coverage == coverage         )      {        span->len = (unsigned short)( span->len + acount );        return;      }      if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS )      {        if ( ras.render_span && count > 0 )          ras.render_span( ras.span_y, count, ras.gray_spans,                           ras.render_span_data );        /* ras.render_span( span->y, ras.gray_spans, count ); */#ifdef DEBUG_GRAYS        if ( ras.span_y >= 0 )        {          int  n;          fprintf( stderr, "y=%3d ", ras.span_y );          span = ras.gray_spans;          for ( n = 0; n < count; n++, span++ )            fprintf( stderr, "[%d..%d]:%02x ",                     span->x, span->x + span->len - 1, span->coverage );          fprintf( stderr, "\n" );        }#endif /* DEBUG_GRAYS */        ras.num_gray_spans = 0;        ras.span_y         = y;        count = 0;        span  = ras.gray_spans;      }      else        span++;      /* add a gray span to the current list */      span->x        = (short)x;      span->len      = (unsigned short)acount;      span->coverage = (unsigned char)coverage;      ras.num_gray_spans++;    }  }#ifdef DEBUG_GRAYS  /* to be called while in the debugger */  gray_dump_cells( RAS_ARG )  {    int  yindex;    for ( yindex = 0; yindex < ras.ycount; yindex++ )    {      PCell  cell;      printf( "%3d:", yindex );      for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )        printf( " (%3d, c:%4d, a:%6d)", cell->x, cell->cover, cell->area );      printf( "\n" );    }  }#endif /* DEBUG_GRAYS */  static void  gray_sweep( RAS_ARG_ const FT_Bitmap*  target )  {    int  yindex;    FT_UNUSED( target );    if ( ras.num_cells == 0 )      return;    ras.num_gray_spans = 0;    for ( yindex = 0; yindex < ras.ycount; yindex++ )    {      PCell   cell  = ras.ycells[yindex];      TCoord  cover = 0;      TCoord  x     = 0;      for ( ; cell != NULL; cell = cell->next )      {        TArea  area;        if ( cell->x > x && cover != 0 )          gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),                      cell->x - x );        cover += cell->cover;        area   = cover * ( ONE_PIXEL * 2 ) - cell->area;        if ( area != 0 && cell->x >= 0 )          gray_hline( RAS_VAR_ cell->x, yindex, area, 1 );        x = cell->x + 1;      }      if ( cover != 0 )        gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),                    ras.count_ex - x );    }    if ( ras.render_span && ras.num_gray_spans > 0 )      ras.render_span( ras.span_y, ras.num_gray_spans,                       ras.gray_spans, ras.render_span_data );  }#ifdef _STANDALONE_  /*************************************************************************/  /*                                                                       */  /*  The following function should only compile in stand_alone mode,      */  /*  i.e., when building this component without the rest of FreeType.     */  /*                                                                       */  /*************************************************************************/  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    FT_Outline_Decompose                                               */  /*                                                                       */  /* <Description>                                                         */  /*    Walks over an outline's structure to decompose it into individual  */  /*    segments and Bezier arcs.  This function is also able to emit      */  /*    `move to' and `close to' operations to indicate the start and end  */  /*    of new contours in the outline.                                    */  /*                                                                       */  /* <Input>                                                               */  /*    outline        :: A pointer to the source target.                  */  /*                                                                       */  /*    func_interface :: A table of `emitters', i.e,. function pointers   */  /*                      called during decomposition to indicate path     */  /*                      operations.                                      */  /*                                                                       */  /*    user           :: A typeless pointer which is passed to each       */  /*                      emitter during the decomposition.  It can be     */  /*                      used to store the state during the               */  /*                      decomposition.                                   */  /*                                                                       */  /* <Return>                                                              */  /*    Error code.  0 means success.                                      */  /*                                                                       */  static  int  FT_Outline_Decompose( const FT_Outline*        outline,                             const FT_Outline_Funcs*  func_interface,                             void*                    user )  {#undef SCALED#if 0#define SCALED( x )  ( ( (x) << shift ) - delta )#else#define SCALED( x )  (x)#endif    FT_Vector   v_last;    FT_Vector   v_control;    FT_Vector   v_start;    FT_Vector*  point;    FT_Vector*  limit;    char*       tags;    int   n;         /* index of contour in outline     */    int   first;     /* index of first point in contour */    int   error;    char  tag;       /* current point's state           */#if 0    int   shift = func_interface->shift;    TPos  delta = func_interface->delta;#endif    first = 0;    for ( n = 0; n < outline->n_contours; n++ )    {      int  last;  /* index of last point in contour */      last  = outline->contours[n];      limit = outline->points + last;      v_start = outline->points[first];      v_last  = outline->points[last];      v_start.x = SCALED( v_start.x );      v_start.y = SCALED( v_start.y );      v_last.x  = SCALED( v_last.x );      v_last.y  = SCALED( v_last.y );      v_control = v_start;      point = outline->points + first;      tags  = 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( 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--;      }      error = func_interface->move_to( &v_start, user );      if ( error )        goto Exit;      while ( point < limit )      {        point++;        tags++;        tag = FT_CURVE_TAG( tags[0] );        switch ( tag )        {        case FT_CURVE_TAG_ON:  /* emit a single line_to */          {            FT_Vector  vec;            vec.x = SCALED( point->x );            vec.y = SCALED( point->y );            error = func_interface->line_to( &vec, user );            if ( error )              goto Exit;            continue;          }        case FT_CURVE_TAG_CONIC:  /* consume conic arcs */          {            v_control.x = SCALED( point->x );            v_control.y = SCALED( point->y );          Do_Conic:

⌨️ 快捷键说明

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