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

📄 ahglyph.c

📁 qt-embedded-2.3.8.tar.gz源码
💻 C
📖 第 1 页 / 共 3 页
字号:
        }      }      /* compute directions of in & out vectors */      {        for ( point = points; point < point_limit; point++ )        {          AH_Point*  prev;          AH_Point*  next;          FT_Vector  vec;          prev  = point->prev;          vec.x = point->fx - prev->fx;          vec.y = point->fy - prev->fy;          point->in_dir = ah_compute_direction( vec.x, vec.y );#ifndef AH_OPTION_NO_WEAK_INTERPOLATION          point->in_angle = ah_angle( &vec );#endif          next  = point->next;          vec.x = next->fx - point->fx;          vec.y = next->fy - point->fy;          point->out_dir = ah_compute_direction( vec.x, vec.y );#ifndef AH_OPTION_NO_WEAK_INTERPOLATION          point->out_angle = ah_angle( &vec );          {            AH_Angle  delta = point->in_angle - point->out_angle;            if ( delta < 0 )              delta = -delta;            if ( delta < 2 )              point->flags |= ah_flah_weak_interpolation;          }#if 0          if ( point->flags & ( ah_flah_conic | ah_flah_cubic ) )            point->flags |= ah_flah_weak_interpolation;#endif#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */#ifdef AH_OPTION_NO_STRONG_INTERPOLATION          point->flags |= ah_flah_weak_interpolation;#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_flah_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 */            memset( 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 */          memset( 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 */          memset( 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   = 32000;        AH_Segment*  best_segment = 0;        /* the fake segments are introduced to hint the metrics -- */        /* we must never link them to anything                     */        if ( seg1->first == seg1->last )          continue;        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 = ( seg1->dir == outline->horz_major_dir ||                       seg1->dir == outline->vert_major_dir );            is_pos = pos1 > pos2;            if ( pos1 == pos2 || !(is_dir ^ is_pos) )              continue;            /* Check the two segments.  We now have a better algorithm */            /* that doesn't rely on the segment points themselves but  */            /* on their relative position.  This gets rids of many     */            /* unpleasant artefacts and incorrect stem/serifs          */            /* computations.                                           */            /* first of all, compute the size of the `common' height */            {              FT_Pos  min = seg1->min_coord;              FT_Pos  max = seg1->max_coord;              FT_Pos  len, score;              FT_Pos  size1, size2;              size1 = max - min;              size2 = seg2->max_coord - seg2->min_coord;              if ( min < seg2->min_coord )                min = seg2->min_coord;              if ( max < seg2->max_coord )                max = seg2->max_coord;              len   = max - min;              score = seg2->pos - seg1->pos;              if ( score < 0 )                score = -score;              /* before comparing the scores, take care that the segments */              /* are really facing each other (often not for italics..)   */              if ( 4 * len >= size1 && 4 * len >= size2 )                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++;        }      } /* edges 1 */      /* now, compute the `serif' segments */      for ( seg1 = segments; seg1 < segment_limit; seg1++ )      {        seg2 = seg1->link;        if ( seg2 && seg2->link != seg1 )        {          seg1->link  = 0;          seg1->serif = seg2->link;        }      }      ah_setup_uv( outline, ah_uv_fxy );      segments      = outline->vert_segments;      segment_limit = segments + outline->num_vsegments;    }  }#ifdef AH_DEBUG_GLYPH  /* A function used to dump the array of linked segments */  void  ah_dump_segments( AH_Outline*  outline )  {    AH_Segment*  segments;    AH_Segment*  segment_limit;    AH_Point*    points;    FT_Int       dimension;

⌨️ 快捷键说明

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