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

📄 afcjk.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 3 页
字号:
    }    return delta;  }  static void  af_cjk_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_Pos        delta    = 0;    FT_Int        skipped  = 0;    /* now we align all stem edges. */    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 )      {        skipped++;        continue;      }      /* now align the stem */      if ( edge2 < edge )      {        af_cjk_align_linked_edge( hints, dim, edge2, edge );        edge->flags |= AF_EDGE_DONE;        continue;      }      if ( dim != AF_DIMENSION_VERT && !anchor )      {#if 0        if ( fixedpitch )        {          AF_Edge     left  = edge;          AF_Edge     right = edge_limit - 1;          AF_EdgeRec  left1, left2, right1, right2;          FT_Pos      target, center1, center2;          FT_Pos      delta1, delta2, d1, d2;          while ( right > left && !right->link )            right--;          left1  = *left;          left2  = *left->link;          right1 = *right->link;          right2 = *right;          delta  = ( ( ( hinter->pp2.x + 32 ) & -64 ) - hinter->pp2.x ) / 2;          target = left->opos + ( right->opos - left->opos ) / 2 + delta - 16;          delta1  = delta;          delta1 += af_hint_normal_stem( hints, left, left->link,                                         delta1, 0 );          if ( left->link != right )            af_hint_normal_stem( hints, right->link, right, delta1, 0 );          center1 = left->pos + ( right->pos - left->pos ) / 2;          if ( center1 >= target )            delta2 = delta - 32;          else            delta2 = delta + 32;          delta2 += af_hint_normal_stem( hints, &left1, &left2, delta2, 0 );          if ( delta1 != delta2 )          {            if ( left->link != right )              af_hint_normal_stem( hints, &right1, &right2, delta2, 0 );            center2 = left1.pos + ( right2.pos - left1.pos ) / 2;            d1 = center1 - target;            d2 = center2 - target;            if ( FT_ABS( d2 ) < FT_ABS( d1 ) )            {              left->pos       = left1.pos;              left->link->pos = left2.pos;              if ( left->link != right )              {                right->link->pos = right1.pos;                right->pos       = right2.pos;              }              delta1 = delta2;            }          }          delta               = delta1;          right->link->flags |= AF_EDGE_DONE;          right->flags       |= AF_EDGE_DONE;        }        else#endif /* 0 */          delta = af_hint_normal_stem( hints, edge, edge2, 0,                                       AF_DIMENSION_HORZ );      }      else        af_hint_normal_stem( hints, edge, edge2, delta, dim );#if 0      printf( "stem (%d,%d) adjusted (%.1f,%.1f)\n",               edge - edges, edge2 - edges,               ( edge->pos - edge->opos ) / 64.0,               ( edge2->pos - edge2->opos ) / 64.0 );#endif      anchor = edge;      edge->flags  |= AF_EDGE_DONE;      edge2->flags |= AF_EDGE_DONE;    }    /* 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;      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 ( edge1->link == edge1 + 1 &&           edge2->link == edge2 + 1 &&           edge3->link == edge3 + 1 && 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 ( !skipped )      return;    /*     *  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_cjk_align_serif_edge( hints, edge->serif, edge );        edge->flags |= AF_EDGE_DONE;        skipped--;      }    }    if ( !skipped )      return;    for ( edge = edges; edge < edge_limit; edge++ )    {      AF_Edge  before, after;      if ( edge->flags & AF_EDGE_DONE )        continue;      before = after = edge;      while ( --before >= edges )        if ( before->flags & AF_EDGE_DONE )          break;      while ( ++after < edge_limit )        if ( after->flags & AF_EDGE_DONE )          break;      if ( before >= edges || after < edge_limit )      {        if ( before < edges )          af_cjk_align_serif_edge( hints, after, edge );        else if ( after >= edge_limit )          af_cjk_align_serif_edge( hints, before, edge );        else          edge->pos = before->pos +            FT_MulDiv( edge->fpos - before->fpos,                       after->pos - before->pos,                       after->fpos - before->fpos );      }    }  }  static void  af_cjk_align_edge_points( 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;    AF_Edge       edge;    FT_Bool       snapping;    snapping = FT_BOOL( ( dim == AF_DIMENSION_HORZ             &&                          AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) )  ||                        ( dim == AF_DIMENSION_VERT             &&                          AF_LATIN_HINTS_DO_VERT_SNAP( hints ) )  );    for ( edge = edges; edge < edge_limit; edge++ )    {      /* move the points of each segment     */      /* in each edge to the edge's position */      AF_Segment  seg = edge->first;      if ( snapping )      {        do        {          AF_Point  point = seg->first;          for (;;)          {            if ( dim == AF_DIMENSION_HORZ )            {              point->x      = edge->pos;              point->flags |= AF_FLAG_TOUCH_X;            }            else            {              point->y      = edge->pos;              point->flags |= AF_FLAG_TOUCH_Y;            }            if ( point == seg->last )              break;            point = point->next;          }          seg = seg->edge_next;        } while ( seg != edge->first );      }      else      {        FT_Pos  delta = edge->pos - edge->opos;        do        {          AF_Point  point = seg->first;          for (;;)          {            if ( dim == AF_DIMENSION_HORZ )            {              point->x     += delta;              point->flags |= AF_FLAG_TOUCH_X;            }            else            {              point->y     += delta;              point->flags |= AF_FLAG_TOUCH_Y;            }            if ( point == seg->last )              break;            point = point->next;          }          seg = seg->edge_next;        } while ( seg != edge->first );      }    }  }  static FT_Error  af_cjk_hints_apply( AF_GlyphHints    hints,                      FT_Outline*      outline,                      AF_LatinMetrics  metrics )  {    FT_Error  error;    int       dim;    FT_UNUSED( metrics );    error = af_glyph_hints_reload( hints, outline );    if ( error )      goto Exit;    /* analyze glyph outline */    if ( AF_HINTS_DO_HORIZONTAL( hints ) )    {      error = af_cjk_hints_detect_features( hints, AF_DIMENSION_HORZ );      if ( error )        goto Exit;    }    if ( AF_HINTS_DO_VERTICAL( hints ) )    {      error = af_cjk_hints_detect_features( hints, AF_DIMENSION_VERT );      if ( error )        goto Exit;    }    /* 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 ) )   )      {#ifdef AF_USE_WARPER        if ( dim == AF_DIMENSION_HORZ                                  &&             metrics->root.scaler.render_mode == FT_RENDER_MODE_NORMAL )        {          AF_WarperRec  warper;          FT_Fixed      scale;          FT_Pos        delta;          af_warper_compute( &warper, hints, dim, &scale, &delta );          af_glyph_hints_scale_dim( hints, dim, scale, delta );          continue;        }#endif /* AF_USE_WARPER */        af_cjk_hint_edges( hints, (AF_Dimension)dim );        af_cjk_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 );      }    }#if 0    af_glyph_hints_dump_points( hints );    af_glyph_hints_dump_segments( hints );    af_glyph_hints_dump_edges( hints );#endif    af_glyph_hints_save( hints, outline );  Exit:    return error;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                C J K   S C R I P T   C L A S S                *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  static const AF_Script_UniRangeRec  af_cjk_uniranges[] =  {#if 0    { 0x0100,  0xFFFF },  /* why this? */#endif    { 0x2E80,  0x2EFF },  /* CJK Radicals Supplement */    { 0x2F00,  0x2FDF },  /* Kangxi Radicals */    { 0x3000,  0x303F },  /* CJK Symbols and Punctuation */    { 0x3040,  0x309F },  /* Hiragana */    { 0x30A0,  0x30FF },  /* Katakana */    { 0x3100,  0x312F },  /* Bopomofo */    { 0x3130,  0x318F },  /* Hangul Compatibility Jamo */    { 0x31A0,  0x31BF },  /* Bopomofo Extended */    { 0x31C0,  0x31EF },  /* CJK Strokes */    { 0x31F0,  0x31FF },  /* Katakana Phonetic Extensions */    { 0x3200,  0x32FF },  /* Enclosed CJK Letters and Months */    { 0x3300,  0x33FF },  /* CJK Compatibility */    { 0x3400,  0x4DBF },  /* CJK Unified Ideographs Extension A */    { 0x4DC0,  0x4DFF },  /* Yijing Hexagram Symbols */    { 0x4E00,  0x9FFF },  /* CJK Unified Ideographs */    { 0xF900,  0xFAFF },  /* CJK Compatibility Ideographs */    { 0xFE30,  0xFE4F },  /* CJK Compatibility Forms */    { 0xFF00,  0xFFEF },  /* Halfwidth and Fullwidth Forms */    { 0x20000, 0x2A6DF }, /* CJK Unified Ideographs Extension B */    { 0x2F800, 0x2FA1F }, /* CJK Compatibility Ideographs Supplement */    { 0,       0 }  };  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec  af_cjk_script_class =  {    AF_SCRIPT_CJK,    af_cjk_uniranges,    sizeof( AF_LatinMetricsRec ),    (AF_Script_InitMetricsFunc) af_cjk_metrics_init,    (AF_Script_ScaleMetricsFunc)af_cjk_metrics_scale,    (AF_Script_DoneMetricsFunc) NULL,    (AF_Script_InitHintsFunc)   af_cjk_hints_init,    (AF_Script_ApplyHintsFunc)  af_cjk_hints_apply  };#else /* !AF_CONFIG_OPTION_CJK */  static const AF_Script_UniRangeRec  af_cjk_uniranges[] =  {    { 0, 0 }  };  FT_CALLBACK_TABLE_DEF const AF_ScriptClassRec  af_cjk_script_class =  {    AF_SCRIPT_CJK,    af_cjk_uniranges,    sizeof( AF_LatinMetricsRec ),    (AF_Script_InitMetricsFunc) NULL,    (AF_Script_ScaleMetricsFunc)NULL,    (AF_Script_DoneMetricsFunc) NULL,    (AF_Script_InitHintsFunc)   NULL,    (AF_Script_ApplyHintsFunc)  NULL  };#endif /* !AF_CONFIG_OPTION_CJK *//* END */

⌨️ 快捷键说明

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