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

📄 ahhint.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
          edge1->pos    = blue[0];          edge1->flags |= AH_EDGE_DONE;          if ( edge2 && !edge2->blue_edge )          {            ah_align_linked_edge( hinter, edge1, edge2, dimension );            edge2->flags |= AH_EDGE_DONE;          }          if ( !anchor )            anchor = edge;        }      }      /* now we will align all stem edges, trying to maintain the */      /* relative order of stems in the glyph                     */      for ( edge = edges; edge < edge_limit; edge++ )      {        AH_EdgeRec*  edge2;        if ( edge->flags & AH_EDGE_DONE )          continue;        /* skip all non-stem edges */        edge2 = edge->link;        if ( !edge2 )        {          has_serifs++;          continue;        }        /* now align the stem */        /* this should not happen, but it's better to be safe */        if ( edge2->blue_edge || edge2 < edge )        {          ah_align_linked_edge( hinter, edge2, edge, dimension );          edge->flags |= AH_EDGE_DONE;          continue;        }        if ( !anchor )        {#ifdef FT_CONFIG_CHESTER_STEM          FT_Pos  org_len, org_center, cur_len;          FT_Pos  cur_pos1, error1, error2, u_off, d_off;          org_len = edge2->opos - edge->opos;          cur_len = ah_compute_stem_width( hinter, dimension, org_len,                                           edge->flags, edge2->flags );          if ( cur_len <= 64 )            u_off = d_off = 32;          else          {            u_off = 38;            d_off = 26;          }          if ( cur_len < 96 )          {            org_center = edge->opos + ( org_len >> 1 );            cur_pos1   = ( org_center + 32 ) & -64;            error1 = org_center - ( cur_pos1 - u_off );            if ( error1 < 0 )              error1 = -error1;            error2 = org_center - ( cur_pos1 + d_off );            if ( error2 < 0 )              error2 = -error2;            if ( error1 < error2 )              cur_pos1 -= u_off;            else              cur_pos1 += d_off;            edge->pos  = cur_pos1 - cur_len / 2;            edge2->pos = cur_pos1 + cur_len / 2;          }          else            edge->pos = ( edge->opos + 32 ) & -64;          anchor = edge;          edge->flags |= AH_EDGE_DONE;          ah_align_linked_edge( hinter, edge, edge2, dimension );#else /* !FT_CONFIG_CHESTER_STEM */          edge->pos = ( edge->opos + 32 ) & -64;          anchor    = edge;          edge->flags |= AH_EDGE_DONE;          ah_align_linked_edge( hinter, edge, edge2, dimension );#endif /* !FT_CONFIG_CHESTER_STEM */        }        else        {          FT_Pos  org_pos, org_len, org_center, cur_len;          FT_Pos  cur_pos1, cur_pos2, delta1, delta2;          org_pos    = anchor->pos + ( edge->opos - anchor->opos );          org_len    = edge2->opos - edge->opos;          org_center = org_pos + ( org_len >> 1 );#ifdef FT_CONFIG_CHESTER_SERIF          cur_len = ah_compute_stem_width( hinter, dimension, org_len,                                           edge->flags, edge2->flags  );#else  /* !FT_CONFIG_CHESTER_SERIF */          cur_len = ah_compute_stem_width( hinter, dimension, org_len );#endif /* !FT_CONFIG_CHESTER_SERIF */#ifdef FT_CONFIG_CHESTER_STEM          if ( cur_len < 96 )          {            FT_Pos  u_off, d_off;            cur_pos1 = ( org_center + 32 ) & -64;            if (cur_len <= 64 )              u_off = d_off = 32;            else            {              u_off = 38;              d_off = 26;            }            delta1 = org_center - ( cur_pos1 - u_off );            if ( delta1 < 0 )              delta1 = -delta1;            delta2 = org_center - ( cur_pos1 + d_off );            if ( delta2 < 0 )              delta2 = -delta2;            if ( delta1 < delta2 )              cur_pos1 -= u_off;            else              cur_pos1 += d_off;            edge->pos  = cur_pos1 - cur_len / 2;            edge2->pos = cur_pos1 + cur_len / 2;          }          else          {            org_pos    = anchor->pos + ( edge->opos - anchor->opos );            org_len    = edge2->opos - edge->opos;            org_center = org_pos + ( org_len >> 1 );            cur_len    = ah_compute_stem_width( hinter, dimension, org_len,                                                edge->flags, edge2->flags );            cur_pos1   = ( org_pos + 32 ) & -64;            delta1     = ( cur_pos1 + ( cur_len >> 1 ) - org_center );            if ( delta1 < 0 )              delta1 = -delta1;            cur_pos2   = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len;            delta2     = ( cur_pos2 + ( cur_len >> 1 ) - org_center );            if ( delta2 < 0 )              delta2 = -delta2;            edge->pos  = ( delta1 < delta2 ) ? cur_pos1 : cur_pos2;            edge2->pos = edge->pos + cur_len;          }#else /* !FT_CONFIG_CHESTER_STEM */          cur_pos1   = ( org_pos + 32 ) & -64;          delta1     = ( cur_pos1 + ( cur_len >> 1 ) - org_center );          if ( delta1 < 0 )            delta1 = -delta1;          cur_pos2   = ( ( org_pos + org_len + 32 ) & -64 ) - cur_len;          delta2     = ( cur_pos2 + ( cur_len >> 1 ) - org_center );          if ( delta2 < 0 )            delta2 = -delta2;          edge->pos  = ( delta1 <= delta2 ) ? cur_pos1 : cur_pos2;          edge2->pos = edge->pos + cur_len;#endif /* !FT_CONFIG_CHESTER_STEM */          edge->flags  |= AH_EDGE_DONE;          edge2->flags |= AH_EDGE_DONE;          if ( edge > edges && edge->pos < edge[-1].pos )            edge->pos = edge[-1].pos;        }      }      /* make sure that lowercase m's maintain their symmetry */      /* In general, lowercase m's have six vertical edges if they are sans */      /* serif, or twelve if they are avec serif.  This implementation is   */      /* based on that assumption, and seems to work very well with most    */      /* faces.  However, if for a certain face this assumption is not      */      /* true, the m is just rendered like before.  In addition, any stem   */      /* correction will only be applied to symmetrical glyphs (even if the */      /* glyph is not an m), so the potential for unwanted distortion is    */      /* relatively low.                                                    */      /* We don't handle horizontal edges since we can't easily assure that */      /* the third (lowest) stem aligns with the base line; it might end up */      /* one pixel higher or lower.                                         */      n_edges = edge_limit - edges;      if ( !dimension && ( n_edges == 6 || n_edges == 12 ) )      {        AH_EdgeRec  *edge1, *edge2, *edge3;        FT_Pos       dist1, dist2, span, delta;        if ( n_edges == 6 )        {          edge1 = edges;          edge2 = edges + 2;          edge3 = edges + 4;        }        else        {          edge1 = edges + 1;          edge2 = edges + 5;          edge3 = edges + 9;        }        dist1 = edge2->opos - edge1->opos;        dist2 = edge3->opos - edge2->opos;        span = dist1 - dist2;        if ( span < 0 )          span = -span;        if ( span < 8 )        {          delta = edge3->pos - ( 2 * edge2->pos - edge1->pos );          edge3->pos -= delta;          if ( edge3->link )            edge3->link->pos -= delta;          /* move the serifs along with the stem */          if ( n_edges == 12 )          {            ( edges + 8 )->pos -= delta;            ( edges + 11 )->pos -= delta;          }          edge3->flags |= AH_EDGE_DONE;          if ( edge3->link )            edge3->link->flags |= AH_EDGE_DONE;        }      }      if ( !has_serifs )        goto Next_Dimension;      /* now hint the remaining edges (serifs and single) in order */      /* to complete our processing                                */      for ( edge = edges; edge < edge_limit; edge++ )      {        if ( edge->flags & AH_EDGE_DONE )          continue;        if ( edge->serif )          ah_align_serif_edge( hinter, edge->serif, edge, dimension );        else if ( !anchor )        {          edge->pos = ( edge->opos + 32 ) & -64;          anchor    = edge;        }        else          edge->pos = anchor->pos +                      ( ( edge->opos-anchor->opos + 32 ) & -64 );        edge->flags |= AH_EDGE_DONE;        if ( edge > edges && edge->pos < edge[-1].pos )          edge->pos = edge[-1].pos;        if ( edge + 1 < edge_limit        &&             edge[1].flags & AH_EDGE_DONE &&             edge->pos > edge[1].pos      )          edge->pos = edge[1].pos;      }    Next_Dimension:      edges      = outline->vert_edges;      edge_limit = edges + outline->num_vedges;    }  }  /*************************************************************************/  /*************************************************************************/  /*************************************************************************/  /****                                                                 ****/  /****       P O I N T   H I N T I N G                                 ****/  /****                                                                 ****/  /*************************************************************************/  /*************************************************************************/  /*************************************************************************/  static void  ah_hinter_align_edge_points( AH_Hinter  hinter )  {    AH_Outline  outline = hinter->glyph;    AH_Edge     edges;    AH_Edge     edge_limit;    FT_Int      dimension;    edges      = outline->horz_edges;    edge_limit = edges + outline->num_hedges;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Edge  edge;      edge = edges;      for ( ; edge < edge_limit; edge++ )      {        /* move the points of each segment     */        /* in each edge to the edge's position */        AH_Segment  seg = edge->first;        do        {          AH_Point  point = seg->first;          for (;;)          {            if ( dimension )            {              point->y      = edge->pos;              point->flags |= AH_FLAG_TOUCH_Y;            }            else            {              point->x      = edge->pos;              point->flags |= AH_FLAG_TOUCH_X;            }            if ( point == seg->last )              break;            point = point->next;          }          seg = seg->edge_next;        } while ( seg != edge->first );      }      edges      = outline->vert_edges;      edge_limit = edges + outline->num_vedges;    }  }  /* hint the strong points -- this is equivalent to the TrueType `IP' */  /* hinting instruction                                               */  static void  ah_hinter_align_strong_points( AH_Hinter  hinter )  {    AH_Outline  outline = hinter->glyph;    FT_Int      dimension;    AH_Edge     edges;    AH_Edge     edge_limit;    AH_Point    points;    AH_Point    point_limit;    AH_Flags    touch_flag;    points      = outline->points;    point_limit = points + outline->num_points;    edges       = outline->horz_edges;    edge_limit  = edges + outline->num_hedges;    touch_flag  = AH_FLAG_TOUCH_Y;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Point  point;      AH_Edge   edge;      if ( edges < edge_limit )        for ( point = points; point < point_limit; point++ )        {          FT_Pos  u, ou, fu;  /* point position */          FT_Pos  delta;          if ( point->flags & touch_flag )            continue;#ifndef AH_OPTION_NO_WEAK_INTERPOLATION          /* if this point is candidate to weak interpolation, we will  */          /* interpolate it after all strong points have been processed */          if (  ( point->flags & AH_FLAG_WEAK_INTERPOLATION ) &&               !( point->flags & AH_FLAG_INFLECTION )         )            continue;#endif          if ( dimension )          {            u  = point->fy;            ou = point->oy;          }          else          {            u  = point->fx;            ou = point->ox;          }          fu = u;          /* is the point before the first edge? */          edge  = edges;          delta = edge->fpos - u;          if ( delta >= 0 )          {            u = edge->pos - ( edge->opos - ou );            goto Store_Point;          }          /* is the point after the last edge? */          edge  = edge_limit - 1;          delta = u - edge->fpos;          if ( delta >= 0 )          {            u = edge->pos + ( ou - edge->opos );            goto Store_Point;          }#if 1          {            FT_UInt  min, max, mid;            FT_Pos   fpos;            /* find enclosing edges */            min = 0;            max = edge_limit - edges;            while ( min < max )            {              mid  = ( max + min ) >> 1;              edge = edges + mid;              fpos = edge->fpos;              if ( u < fpos )                max = mid;              else if ( u > fpos )                min = mid + 1;              else

⌨️ 快捷键说明

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