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

📄 aflatin.c

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 C
📖 第 1 页 / 共 4 页
字号:
      dist = af_latin_snap_width( axis->widths, axis->width_count, dist );      if ( vertical )      {        /* in the case of vertical hinting, always round */        /* the stem heights to integer pixels            */        if ( dist >= 64 )          dist = ( dist + 16 ) & ~63;        else          dist = 64;      }      else      {        if ( AF_LATIN_HINTS_DO_MONO( hints ) )        {          /* monochrome horizontal hinting: snap widths to integer pixels */          /* with a different threshold                                   */          if ( dist < 64 )            dist = 64;          else            dist = ( dist + 32 ) & ~63;        }        else        {          /* for horizontal anti-aliased hinting, we adopt a more subtle */          /* approach: we strengthen small stems, round stems whose size */          /* is between 1 and 2 pixels to an integer, otherwise nothing  */          if ( dist < 48 )            dist = ( dist + 64 ) >> 1;          else if ( dist < 128 )            dist = ( dist + 22 ) & ~63;          else            /* round otherwise to prevent color fringes in LCD mode */            dist = ( dist + 32 ) & ~63;        }      }    }  Done_Width:    if ( sign )      dist = -dist;    return dist;  }  /* align one stem edge relative to the previous stem edge */  static void  af_latin_align_linked_edge( AF_GlyphHints  hints,                              AF_Dimension   dim,                              AF_Edge        base_edge,                              AF_Edge        stem_edge )  {    FT_Pos  dist = stem_edge->opos - base_edge->opos;    FT_Pos  fitted_width = af_latin_compute_stem_width(                             hints, dim, dist,                             (AF_Edge_Flags)base_edge->flags,                             (AF_Edge_Flags)stem_edge->flags );    stem_edge->pos = base_edge->pos + fitted_width;  }  static void  af_latin_align_serif_edge( AF_GlyphHints  hints,                             AF_Edge        base,                             AF_Edge        serif )  {    FT_UNUSED( hints );    serif->pos = base->pos + (serif->opos - base->opos);  }  /*************************************************************************/  /*************************************************************************/  /*************************************************************************/  /****                                                                 ****/  /****                    E D G E   H I N T I N G                      ****/  /****                                                                 ****/  /*************************************************************************/  /*************************************************************************/  /*************************************************************************/  FT_LOCAL_DEF( void )  af_latin_hint_edges( AF_GlyphHints  hints,                       AF_Dimension   dim )  {    AF_AxisHints  axis       = &hints->axis[dim];    AF_Edge       edges      = axis->edges;    AF_Edge       edge_limit = edges + axis->num_edges;    FT_Int        n_edges;    AF_Edge       edge;    AF_Edge       anchor     = 0;    FT_Int        has_serifs = 0;    /* we begin by aligning all stems relative to the blue zone */    /* if needed -- that's only for horizontal edges            */    if ( dim == AF_DIMENSION_VERT )    {      for ( edge = edges; edge < edge_limit; edge++ )      {        AF_Width  blue;        AF_Edge   edge1, edge2;        if ( edge->flags & AF_EDGE_DONE )          continue;        blue  = edge->blue_edge;        edge1 = NULL;        edge2 = edge->link;        if ( blue )        {          edge1 = edge;        }        else if ( edge2 && edge2->blue_edge )        {          blue  = edge2->blue_edge;          edge1 = edge2;          edge2 = edge;        }        if ( !edge1 )          continue;        edge1->pos    = blue->fit;        edge1->flags |= AF_EDGE_DONE;        if ( edge2 && !edge2->blue_edge )        {          af_latin_align_linked_edge( hints, dim, edge1, edge2 );          edge2->flags |= AF_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++ )    {      AF_Edge  edge2;      if ( edge->flags & AF_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 )      {        af_latin_align_linked_edge( hints, dim, edge2, edge );        edge->flags |= AF_EDGE_DONE;        continue;      }      if ( !anchor )      {        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 = af_latin_compute_stem_width(                    hints, dim, org_len,                    (AF_Edge_Flags)edge->flags,                    (AF_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   = FT_PIX_ROUND( org_center );          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 = FT_PIX_ROUND( edge->opos );        anchor = edge;        edge->flags |= AF_EDGE_DONE;        af_latin_align_linked_edge( hints, dim, edge, edge2 );      }      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 );        cur_len = af_latin_compute_stem_width(                   hints, dim, org_len,                   (AF_Edge_Flags)edge->flags,                   (AF_Edge_Flags)edge2->flags );        if ( cur_len < 96 )        {          FT_Pos  u_off, d_off;          cur_pos1 = FT_PIX_ROUND( org_center );          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    = af_latin_compute_stem_width(                         hints, dim, org_len,                         (AF_Edge_Flags)edge->flags,                         (AF_Edge_Flags)edge2->flags );          cur_pos1   = FT_PIX_ROUND( org_pos );          delta1     = cur_pos1 + ( cur_len >> 1 ) - org_center;          if ( delta1 < 0 )            delta1 = -delta1;          cur_pos2   = FT_PIX_ROUND( org_pos + org_len ) - 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;        }        edge->flags  |= AF_EDGE_DONE;        edge2->flags |= AF_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 with serifs.  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 ( dim == AF_DIMENSION_HORZ && ( n_edges == 6 || n_edges == 12 ) )    {      AF_Edge  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 |= AF_EDGE_DONE;        if ( edge3->link )          edge3->link->flags |= AF_EDGE_DONE;      }    }    if ( has_serifs || !anchor )    {      /*       *  now hint the remaining edges (serifs and single) in order       *  to complete our processing       */      for ( edge = edges; edge < edge_limit; edge++ )      {        if ( edge->flags & AF_EDGE_DONE )          continue;        if ( edge->serif )          af_latin_align_serif_edge( hints, edge->serif, edge );        else if ( !anchor )        {          edge->pos = FT_PIX_ROUND( edge->opos );          anchor    = edge;        }        else          edge->pos = anchor->pos +                      FT_PIX_ROUND( edge->opos - anchor->opos );        edge->flags |= AF_EDGE_DONE;        if ( edge > edges && edge->pos < edge[-1].pos )          edge->pos = edge[-1].pos;        if ( edge + 1 < edge_limit        &&             edge[1].flags & AF_EDGE_DONE &&             edge->pos > edge[1].pos      )          edge->pos = edge[1].pos;      }    }  }  static FT_Error  af_latin_hints_apply( AF_GlyphHints    hints,                        FT_Outline*      outline,                        AF_LatinMetrics  metrics )  {    FT_Error  error;    int       dim;    error = af_glyph_hints_reload( hints, outline );    if ( error )      goto Exit;    /* analyze glyph outline */    if ( AF_HINTS_DO_HORIZONTAL( hints ) )    {      error = af_latin_hints_detect_features( hints, AF_DIMENSION_HORZ );      if ( error )        goto Exit;    }    if ( AF_HINTS_DO_VERTICAL( hints ) )    {      error = af_latin_hints_detect_features( hints, AF_DIMENSION_VERT );      if ( error )        goto Exit;      af_latin_hints_compute_blue_edges( hints, metrics );    }    /* grid-fit the outline */    for ( dim = 0; dim < AF_DIMENSION_MAX; dim++ )    {      if ( ( dim == AF_DIMENSION_HORZ && AF_HINTS_DO_HORIZONTAL( hints ) ) ||           ( dim == AF_DIMENSION_VERT && AF_HINTS_DO_VERTICAL( hints ) )   )      {        af_latin_hint_edges( hints, (AF_Dimension)dim );        af_glyph_hints_align_edge_points( hints, (AF_Dimension)dim );        af_glyph_hints_align_strong_points( hints, (AF_Dimension)dim );        af_glyph_hints_align_weak_points( hints, (AF_Dimension)dim );      }    }    af_glyph_hints_save( hints, outline );  Exit:    return error;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****              L A T I N   S C R I P T   C L A S S              *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  static const AF_Script_UniRangeRec  af_latin_uniranges[] =  {    { 32,  127 },    /* XXX: TODO: Add new Unicode ranges here! */    { 160, 255 },    { 0,   0 }  };  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec  af_latin_script_class =  {    AF_SCRIPT_LATIN,    af_latin_uniranges,    sizeof( AF_LatinMetricsRec ),    (AF_Script_InitMetricsFunc) af_latin_metrics_init,    (AF_Script_ScaleMetricsFunc)af_latin_metrics_scale,    (AF_Script_DoneMetricsFunc) NULL,    (AF_Script_InitHintsFunc)   af_latin_hints_init,    (AF_Script_ApplyHintsFunc)  af_latin_hints_apply  };/* END */

⌨️ 快捷键说明

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