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

📄 ahglyph.c

📁 a very goog book
💻 C
📖 第 1 页 / 共 3 页
字号:
          point->oy = point->y = FT_MulFix( vec->y, y_scale );          point->flags = 0;        }      }      /* compute Bezier flags */      {        char*  tag = source->tags;        for ( point = points; point < point_limit; point++, tag++ )        {          switch ( FT_CURVE_TAG( *tag ) )          {          case FT_Curve_Tag_Conic:            point->flags = ah_flag_conic; break;          case FT_Curve_Tag_Cubic:            point->flags = ah_flag_cubic; break;          default:            ;          }        }      }      /* compute `next' and `prev' */      {        FT_Int     contour_index;        AH_Point*  prev;        AH_Point*  first;        AH_Point*  end;        contour_index = 0;        first = points;        end   = points + source->contours[0];        prev  = end;        for ( point = points; point < point_limit; point++ )        {          point->prev = prev;          if ( point < end )          {            point->next = point + 1;            prev        = point;          }          else          {            point->next = first;            contour_index++;            if ( point + 1 < point_limit )            {              end   = points + source->contours[contour_index];              first = point + 1;              prev  = end;            }          }        }      }      /* set-up the contours array */      {        AH_Point**  contour       = outline->contours;        AH_Point**  contour_limit = contour + outline->num_contours;        short*      end           = source->contours;        short       idx           = 0;        for ( ; contour < contour_limit; contour++, end++ )        {          contour[0] = points + idx;          idx        = (short)( end[0] + 1 );        }      }      /* compute directions of in & out vectors */      {        for ( point = points; point < point_limit; point++ )        {          AH_Point*  prev;          AH_Point*  next;          FT_Vector  ivec, ovec;          prev   = point->prev;          ivec.x = point->fx - prev->fx;          ivec.y = point->fy - prev->fy;          point->in_dir = ah_compute_direction( ivec.x, ivec.y );          next   = point->next;          ovec.x = next->fx - point->fx;          ovec.y = next->fy - point->fy;          point->out_dir = ah_compute_direction( ovec.x, ovec.y );#ifndef AH_OPTION_NO_WEAK_INTERPOLATION          if ( point->flags & (ah_flag_conic | ah_flag_cubic) )          {          Is_Weak_Point:            point->flags |= ah_flag_weak_interpolation;          }          else if ( point->out_dir == point->in_dir )          {            AH_Angle  angle_in, angle_out, delta;            if ( point->out_dir != ah_dir_none )              goto Is_Weak_Point;            angle_in  = ah_angle( &ivec );            angle_out = ah_angle( &ovec );            delta     = angle_in - angle_out;            if ( delta > AH_PI )              delta = AH_2PI - delta;            if ( delta < 0 )              delta = -delta;            if ( delta < 2 )              goto Is_Weak_Point;          }          else if ( point->in_dir == -point->out_dir )            goto Is_Weak_Point;#endif        }      }    }  Exit:    return error;  }  FT_LOCAL_DEF( void )  ah_setup_uv( AH_Outline*  outline,               AH_UV        source )  {    AH_Point*  point       = outline->points;    AH_Point*  point_limit = point + outline->num_points;    for ( ; point < point_limit; point++ )    {      FT_Pos  u, v;      switch ( source )      {      case ah_uv_fxy:        u = point->fx;        v = point->fy;        break;      case ah_uv_fyx:        u = point->fy;        v = point->fx;        break;      case ah_uv_oxy:        u = point->ox;        v = point->oy;        break;      case ah_uv_oyx:        u = point->oy;        v = point->ox;        break;      case ah_uv_yx:        u = point->y;        v = point->x;        break;      case ah_uv_ox:        u = point->x;        v = point->ox;        break;      case ah_uv_oy:        u = point->y;        v = point->oy;        break;      default:        u = point->x;        v = point->y;        break;      }      point->u = u;      point->v = v;    }  }  FT_LOCAL_DEF( void )  ah_outline_compute_segments( AH_Outline*  outline )  {    int           dimension;    AH_Segment*   segments;    FT_Int*       p_num_segments;    AH_Direction  segment_dir;    AH_Direction  major_dir;    segments       = outline->horz_segments;    p_num_segments = &outline->num_hsegments;    major_dir      = ah_dir_right;      /* This value must be positive! */    segment_dir    = major_dir;    /* set up (u,v) in each point */    ah_setup_uv( outline, ah_uv_fyx );    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Point**   contour       =  outline->contours;      AH_Point**   contour_limit =  contour + outline->num_contours;      AH_Segment*  segment       =  segments;      FT_Int       num_segments  =  0;#ifdef AH_HINT_METRICS      AH_Point*    min_point     =  0;      AH_Point*    max_point     =  0;      FT_Pos       min_coord     =  32000;      FT_Pos       max_coord     = -32000;#endif      /* do each contour separately */      for ( ; contour < contour_limit; contour++ )      {        AH_Point*  point   = contour[0];        AH_Point*  last    = point->prev;        int        on_edge = 0;        FT_Pos     min_pos = +32000;  /* minimum segment pos != min_coord */        FT_Pos     max_pos = -32000;  /* maximum segment pos != max_coord */        FT_Bool    passed;#ifdef AH_HINT_METRICS        if ( point->u < min_coord )        {          min_coord = point->u;          min_point = point;        }        if ( point->u > max_coord )        {          max_coord = point->u;          max_point = point;        }#endif        if ( point == last )  /* skip singletons -- just in case? */          continue;        if ( ABS( last->out_dir )  == major_dir &&             ABS( point->out_dir ) == major_dir )        {          /* we are already on an edge, try to locate its start */          last = point;          for (;;)          {            point = point->prev;            if ( ABS( point->out_dir ) != major_dir )            {              point = point->next;              break;            }            if ( point == last )              break;          }        }        last   = point;        passed = 0;        for (;;)        {          FT_Pos  u, v;          if ( on_edge )          {            u = point->u;            if ( u < min_pos )              min_pos = u;            if ( u > max_pos )              max_pos = u;            if ( point->out_dir != segment_dir || point == last )            {              /* we are just leaving an edge; record a new segment! */              segment->last = point;              segment->pos  = ( min_pos + max_pos ) >> 1;              /* a segment is round if either its first or last point */              /* is a control point                                   */              if ( ( segment->first->flags | point->flags ) &                     ah_flag_control                        )                segment->flags |= ah_edge_round;              /* compute segment size */              min_pos = max_pos = point->v;              v = segment->first->v;              if ( v < min_pos )                min_pos = v;              if ( v > max_pos )                max_pos = v;              segment->min_coord = min_pos;              segment->max_coord = max_pos;              on_edge = 0;              num_segments++;              segment++;              /* fallthrough */            }          }          /* now exit if we are at the start/end point */          if ( point == last )          {            if ( passed )              break;            passed = 1;          }          if ( !on_edge && ABS( point->out_dir ) == major_dir )          {            /* this is the start of a new segment! */            segment_dir = point->out_dir;            /* clear all segment fields */            FT_MEM_SET( segment, 0, sizeof ( *segment ) );            segment->dir      = segment_dir;            segment->flags    = ah_edge_normal;            min_pos = max_pos = point->u;            segment->first    = point;            segment->last     = point;            segment->contour  = contour;            on_edge           = 1;#ifdef AH_HINT_METRICS            if ( point == max_point )              max_point = 0;            if ( point == min_point )              min_point = 0;#endif          }          point = point->next;        }      } /* contours */#ifdef AH_HINT_METRICS      /* we need to ensure that there are edges on the left-most and  */      /* right-most points of the glyph in order to hint the metrics; */      /* we do this by inserting fake segments when needed            */      if ( dimension == 0 )      {        AH_Point*  point       =  outline->points;        AH_Point*  point_limit =  point + outline->num_points;        FT_Pos     min_pos     =  32000;        FT_Pos     max_pos     = -32000;        min_point = 0;        max_point = 0;        /* compute minimum and maximum points */        for ( ; point < point_limit; point++ )        {          FT_Pos  x = point->fx;          if ( x < min_pos )          {            min_pos   = x;            min_point = point;          }          if ( x > max_pos )          {            max_pos   = x;            max_point = point;          }        }        /* insert minimum segment */        if ( min_point )        {          /* clear all segment fields */          FT_MEM_SET( segment, 0, sizeof ( *segment ) );          segment->dir   = segment_dir;          segment->flags = ah_edge_normal;          segment->first = min_point;          segment->last  = min_point;          segment->pos   = min_pos;          num_segments++;          segment++;        }        /* insert maximum segment */        if ( max_point )        {          /* clear all segment fields */          FT_MEM_SET( segment, 0, sizeof ( *segment ) );          segment->dir   = segment_dir;          segment->flags = ah_edge_normal;          segment->first = max_point;          segment->last  = max_point;          segment->pos   = max_pos;          num_segments++;          segment++;        }      }#endif /* AH_HINT_METRICS */      *p_num_segments = num_segments;      segments       = outline->vert_segments;      major_dir      = ah_dir_up;      p_num_segments = &outline->num_vsegments;      ah_setup_uv( outline, ah_uv_fxy );    }  }  FT_LOCAL_DEF( void )  ah_outline_link_segments( AH_Outline*  outline )  {    AH_Segment*  segments;    AH_Segment*  segment_limit;    int          dimension;    ah_setup_uv( outline, ah_uv_fyx );    segments      = outline->horz_segments;    segment_limit = segments + outline->num_hsegments;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Segment*  seg1;      AH_Segment*  seg2;      /* now compare each segment to the others */      for ( seg1 = segments; seg1 < segment_limit; seg1++ )      {        FT_Pos       best_score;        AH_Segment*  best_segment;        /* the fake segments are introduced to hint the metrics -- */        /* we must never link them to anything                     */        if ( seg1->first == seg1->last )          continue;        best_segment = seg1->link;        if ( best_segment )          best_score = seg1->score;        else          best_score = 32000;        for ( seg2 = segments; seg2 < segment_limit; seg2++ )          if ( seg1 != seg2 && seg1->dir + seg2->dir == 0 )          {            FT_Pos   pos1 = seg1->pos;            FT_Pos   pos2 = seg2->pos;            FT_Bool  is_dir;            FT_Bool  is_pos;            /* check that the segments are correctly oriented and */            /* positioned to form a black distance                */            is_dir = (FT_Bool)( seg1->dir == outline->horz_major_dir ||                                seg1->dir == outline->vert_major_dir );            is_pos = (FT_Bool)( pos1 > pos2 );            if ( pos1 == pos2 || !(is_dir ^ is_pos) )              continue;            {

⌨️ 快捷键说明

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