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

📄 ahglyph.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
      /*********************************************************************/      /*                                                                   */      /* 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_distance_threshold = FT_DivFix( edge_distance_threshold,                                           scale );      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;          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, straight 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                       */      /* Note that I've tried to remove this loop, setting       * the "edge" field of each segment directly in the       * code above.  For some reason, it slows down execution       * speed -- on a Sun.       */      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;#ifdef FT_CONFIG_CHESTER_SERIF            if ( is_serif )            {              edge->serif   = edge2;              edge2->flags |= AH_EDGE_SERIF;            }            else              edge->link  = edge2;#else /* !FT_CONFIG_CHESTER_SERIF */            if ( is_serif )              edge->serif = edge2;            else              edge->link  = edge2;#endif /* !FT_CONFIG_CHESTER_SERIF */          }          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;    }  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_detect_features                                         */  /*                                                                       */  /* <Description>                                                         */  /*    Performs feature detection on a given AH_OutlineRec object.        */  /*                                                                       */  FT_LOCAL_DEF( void )  ah_outline_detect_features( AH_Outline  outline )  {    ah_outline_compute_segments   ( outline );    ah_outline_link_segments      ( outline );    ah_outline_compute_edges      ( outline );    ah_outline_compute_inflections( outline );  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_compute_blue_edges                                      */  /*                                                                       */  /* <Description>                                                         */  /*    Computes the `blue edges' in a given outline (i.e. those that must */  /*    be snapped to a blue zone edge (top or bottom).                    */  /*                                                                       */  FT_LOCAL_DEF( void )  ah_outline_compute_blue_edges( AH_Outline       outline,                                 AH_Face_Globals  face_globals )  {    AH_Edge     edge       = outline->horz_edges;    AH_Edge     edge_limit = edge + outline->num_hedges;    AH_Globals  globals    = &face_globals->design;    FT_Fixed    y_scale    = outline->y_scale;    FT_Bool     blue_active[AH_BLUE_MAX];    /* compute which blue zones are active, i.e. have their scaled */    /* size < 3/4 pixels                                           */    {      AH_Blue  blue;      FT_Bool  check = 0;      for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )      {        FT_Pos  ref, shoot, dist;        ref   = globals->blue_refs[blue];        shoot = globals->blue_shoots[blue];        dist  = ref - shoot;        if ( dist < 0 )          dist = -dist;        blue_active[blue] = 0;        if ( FT_MulFix( dist, y_scale ) < 48 )        {          blue_active[blue] = 1;          check = 1;        }      }      /* return immediately if no blue zone is active */      if ( !check )        return;    }    /* for each horizontal edge search the blue zone which is closest */    for ( ; edge < edge_limit; edge++ )    {      AH_Blue  blue;      FT_Pos*  best_blue = 0;      FT_Pos   best_dist;  /* initial threshold */      /* compute the initial threshold as a fraction of the EM size */      best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );#ifdef FT_CONFIG_CHESTER_SMALL_F      if ( best_dist > 64 / 2 )        best_dist = 64 / 2;#else      if ( best_dist > 64 / 4 )        best_dist = 64 / 4;#endif      for ( blue = AH_BLUE_CAPITAL_TOP; blue < AH_BLUE_MAX; blue++ )      {        /* if it is a top zone, check for right edges -- if it is a bottom */        /* zone, check for left edges                                      */        /*                                                                 */        /* of course, that's for TrueType XXX                              */        FT_Bool  is_top_blue  =                   FT_BOOL( AH_IS_TOP_BLUE( blue ) );        FT_Bool  is_major_dir =                   FT_BOOL( edge->dir == outline->horz_major_dir );        if ( !blue_active[blue] )          continue;        /* if it is a top zone, the edge must be against the major    */        /* direction; if it is a bottom zone, it must be in the major */        /* direction                                                  */        if ( is_top_blue ^ is_major_dir )        {          FT_Pos   dist;          FT_Pos*  blue_pos = globals->blue_refs + blue;          /* first of all, compare it to the reference position */          dist = edge->fpos - *blue_pos;          if ( dist < 0 )            dist = -dist;          dist = FT_MulFix( dist, y_scale );          if ( dist < best_dist )          {            best_dist = dist;            best_blue = blue_pos;          }          /* now, compare it to the overshoot position if the edge is     */          /* rounded, and if the edge is over the reference position of a */          /* top zone, or under the reference position of a bottom zone   */          if ( edge->flags & AH_EDGE_ROUND && dist != 0 )          {            FT_Bool  is_under_ref = FT_BOOL( edge->fpos < *blue_pos );            if ( is_top_blue ^ is_under_ref )            {              blue_pos = globals->blue_shoots + blue;              dist = edge->fpos - *blue_pos;              if ( dist < 0 )                dist = -dist;              dist = FT_MulFix( dist, y_scale );              if ( dist < best_dist )              {                best_dist = dist;                best_blue = blue_pos;              }            }          }        }      }      if ( best_blue )        edge->blue_edge = best_blue;    }  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_scale_blue_edges                                        */  /*                                                                       */  /* <Description>                                                         */  /*    This function must be called before hinting in order to re-adjust  */  /*    the contents of the detected edges (basically change the `blue     */  /*    edge' pointer from `design units' to `scaled ones').               */  /*                                                                       */  FT_LOCAL_DEF( void )  ah_outline_scale_blue_edges( AH_Outline       outline,                               AH_Face_Globals  globals )  {    AH_Edge  edge       = outline->horz_edges;    AH_Edge  edge_limit = edge + outline->num_hedges;    FT_Pos   delta;    delta = globals->scaled.blue_refs - globals->design.blue_refs;    for ( ; edge < edge_limit; edge++ )    {      if ( edge->blue_edge )        edge->blue_edge += delta;    }  }/* END */

⌨️ 快捷键说明

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