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

📄 ahglyph.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
#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_ZERO( 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;            segment->score    = 32000;            segment->link     = NULL;            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_ZERO( segment );          segment->dir   = segment_dir;          segment->flags = AH_EDGE_NORMAL;          segment->first = min_point;          segment->last  = min_point;          segment->pos   = min_pos;          segment->score = 32000;          segment->link  = NULL;          num_segments++;          segment++;        }        /* insert maximum segment */        if ( max_point )        {          /* clear all segment fields */          FT_ZERO( segment );          segment->dir   = segment_dir;          segment->flags = AH_EDGE_NORMAL;          segment->first = max_point;          segment->last  = max_point;          segment->pos   = max_pos;          segment->score = 32000;          segment->link  = NULL;          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;    AH_Direction  major_dir;    int           dimension;    segments      = outline->horz_segments;    segment_limit = segments + outline->num_hsegments;    major_dir     = outline->horz_major_dir;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Segment  seg1;      AH_Segment  seg2;#if 0      /* 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;            {              FT_Pos  min = seg1->min_coord;              FT_Pos  max = seg1->max_coord;              FT_Pos  len, dist, score;              if ( min < seg2->min_coord )                min = seg2->min_coord;              if ( max > seg2->max_coord )                max = seg2->max_coord;              len = max - min;              if ( len >= 8 )              {                dist = seg2->pos - seg1->pos;                if ( dist < 0 )                  dist = -dist;                score = dist + 3000 / len;                if ( score < best_score )                {                  best_score   = score;                  best_segment = seg2;                }              }            }          }        if ( best_segment )        {          seg1->link  = best_segment;          seg1->score = best_score;          best_segment->num_linked++;        }      }#endif /* 0 */#if 1      /* the following code does the same, but much faster! */      /* now compare each segment to the others */      for ( seg1 = segments; seg1 < segment_limit; seg1++ )      {        /* the fake segments are introduced to hint the metrics -- */        /* we must never link them to anything                     */        if ( seg1->first == seg1->last || seg1->dir != major_dir )          continue;        for ( seg2 = segments; seg2 < segment_limit; seg2++ )          if ( seg2 != seg1 && seg1->dir + seg2->dir == 0 )          {            FT_Pos  pos1 = seg1->pos;            FT_Pos  pos2 = seg2->pos;            FT_Pos  dist = pos2 - pos1;            if ( dist < 0 )              continue;            {              FT_Pos  min = seg1->min_coord;              FT_Pos  max = seg1->max_coord;              FT_Pos  len, score;              if ( min < seg2->min_coord )                min = seg2->min_coord;              if ( max > seg2->max_coord )                max = seg2->max_coord;              len = max - min;              if ( len >= 8 )              {                score = dist + 3000 / len;                if ( score < seg1->score )                {                  seg1->score = score;                  seg1->link  = seg2;                }                if ( score < seg2->score )                {                  seg2->score = score;                  seg2->link  = seg1;                }              }            }          }      }#endif /* 1 */      /* now, compute the `serif' segments */      for ( seg1 = segments; seg1 < segment_limit; seg1++ )      {        seg2 = seg1->link;        if ( seg2 )        {          seg2->num_linked++;          if ( seg2->link != seg1 )          {            seg1->link  = 0;            seg1->serif = seg2->link;          }        }      }      segments      = outline->vert_segments;      segment_limit = segments + outline->num_vsegments;      major_dir     = outline->vert_major_dir;    }  }  static void  ah_outline_compute_edges( AH_Outline  outline )  {    AH_Edge       edges;    AH_Segment    segments;    AH_Segment    segment_limit;    AH_Direction  up_dir;    FT_Int*       p_num_edges;    FT_Int        dimension;    FT_Fixed      scale;    FT_Pos        edge_distance_threshold;    edges         = outline->horz_edges;    segments      = outline->horz_segments;    segment_limit = segments + outline->num_hsegments;    p_num_edges   = &outline->num_hedges;    up_dir        = AH_DIR_RIGHT;    scale         = outline->y_scale;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Edge     edge;      AH_Edge     edge_limit;  /* really == edge + num_edges */      AH_Segment  seg;

⌨️ 快捷键说明

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