add: edge2->flags |= AH_EDGE_SERIF; }
context:   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;      /*********************************************************************/      /*                                                                   */      /* We will begin by generating a sorted table of edges for the       */      /* current direction.  To do so, we simply scan each segment and try */      /* to find an edge in our table that corresponds to its position.    */      /*                                                                   */      /* If no edge is found, we create and insert a new edge in the       */      /* sorted table.  Otherwise, we simply add the segment to the edge's */      /* list which will be processed in the second step to compute the    */      /* edge's properties.                                                */      /*                                                                   */      /* Note that the edges table is sorted along the segment/edge        */      /* position.                                                         */      /*                                                                   */      /*********************************************************************/      edge_distance_threshold = FT_MulFix( outline->edge_distance_threshold,                                           scale );      if ( edge_distance_threshold > 64 / 4 )        edge_distance_threshold = 64 / 4;      edge_limit = edges;      for ( seg = segments; seg < segment_limit; seg++ )      {        AH_Edge  found = 0;        /* look for an edge corresponding to the segment */        for ( edge = edges; edge < edge_limit; edge++ )        {          FT_Pos  dist;          dist = seg->pos - edge->fpos;          if ( dist < 0 )            dist = -dist;          dist = FT_MulFix( dist, scale );          if ( dist < edge_distance_threshold )          {            found = edge;            break;          }        }        if ( !found )        {          /* insert a new edge in the list and */          /* sort according to the position    */          while ( edge > edges && edge[-1].fpos > seg->pos )          {            edge[0] = edge[-1];            edge--;          }          edge_limit++;          /* clear all edge fields */          FT_MEM_ZERO( edge, sizeof ( *edge ) );          /* add the segment to the new edge's list */          edge->first    = seg;          edge->last     = seg;          edge->fpos     = seg->pos;          edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );          seg->edge_next = seg;        }        else        {          /* if an edge was found, simply add the segment to the edge's */          /* list                                                       */          seg->edge_next        = edge->first;          edge->last->edge_next = seg;          edge->last            = seg;        }      }      *p_num_edges = (FT_Int)( edge_limit - edges );      /*********************************************************************/      /*                                                                   */      /* Good, we will now compute each edge's properties according to     */      /* segments found on its position.  Basically, these are:            */      /*                                                                   */      /*  - edge's main direction                                          */      /*  - stem edge, serif edge or both (which defaults to stem then)    */      /*  - rounded edge, straigth or both (which defaults to straight)    */      /*  - link for edge                                                  */      /*                                                                   */      /*********************************************************************/      /* first of all, set the `edge' field in each segment -- this is */      /* required in order to compute edge links                       */      for ( edge = edges; edge < edge_limit; edge++ )      {        seg = edge->first;        if ( seg )          do          {            seg->edge = edge;            seg       = seg->edge_next;          }          while ( seg != edge->first );      }      /* now, compute each edge properties */      for ( edge = edges; edge < edge_limit; edge++ )      {        FT_Int  is_round    = 0;  /* does it contain round segments?    */        FT_Int  is_straight = 0;  /* does it contain straight segments? */        FT_Pos  ups         = 0;  /* number of upwards segments         */        FT_Pos  downs       = 0;  /* number of downwards segments       */        seg = edge->first;        do        {          FT_Bool  is_serif;          /* check for roundness of segment */          if ( seg->flags & AH_EDGE_ROUND )            is_round++;          else            is_straight++;          /* check for segment direction */          if ( seg->dir == up_dir )            ups   += seg->max_coord-seg->min_coord;          else            downs += seg->max_coord-seg->min_coord;          /* check for links -- if seg->serif is set, then seg->link must */          /* be ignored                                                   */          is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );          if ( seg->link || is_serif )          {            AH_Edge     edge2;            AH_Segment  seg2;            edge2 = edge->link;            seg2  = seg->link;            if ( is_serif )            {              seg2  = seg->serif;              edge2 = edge->serif;            }            if ( edge2 )            {              FT_Pos  edge_delta;              FT_Pos  seg_delta;              edge_delta = edge->fpos - edge2->fpos;              if ( edge_delta < 0 )                edge_delta = -edge_delta;              seg_delta = seg->pos - seg2->pos;              if ( seg_delta < 0 )                seg_delta = -seg_delta;              if ( seg_delta < edge_delta )                edge2 = seg2->edge;            }            else              edge2 = seg2->edge;            if ( is_serif )              edge->serif = edge2;            else              edge->link  = edge2;          }          seg = seg->edge_next;        } while ( seg != edge->first );        /* set the round/straight flags */        edge->flags = AH_EDGE_NORMAL;        if ( is_round > 0 && is_round >= is_straight )          edge->flags |= AH_EDGE_ROUND;        /* set the edge's main direction */        edge->dir = AH_DIR_NONE;        if ( ups > downs )          edge->dir = up_dir;        else if ( ups < downs )          edge->dir = - up_dir;        else if ( ups == downs )          edge->dir = 0;  /* both up and down !! */        /* gets rid of serifs if link is set                */        /* XXX: This gets rid of many unpleasant artefacts! */        /*      Example: the `c' in cour.pfa at size 13     */        if ( edge->serif && edge->link )          edge->serif = 0;      }      edges         = outline->vert_edges;      segments      = outline->vert_segments;      segment_limit = segments + outline->num_vsegments;      p_num_edges   = &outline->num_vedges;      up_dir        = AH_DIR_UP;      scale         = outline->x_scale;    }  }