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

📄 pshalgo2.c

📁 a very goog book
💻 C
📖 第 1 页 / 共 3 页
字号:
      if ( dimension == 0 )        vec[n].x = point->cur_u;      else        vec[n].y = point->cur_u;      if ( psh2_point_is_strong( point ) )        tags[n] |= (char)( ( dimension == 0 ) ? 32 : 64 );#ifdef DEBUG_HINTER      if ( dimension == 0 )      {        point->cur_x   = point->cur_u;        point->flags_x = point->flags;      }      else      {        point->cur_y   = point->cur_u;        point->flags_y = point->flags;      }#endif      point++;    }  }#define PSH2_STRONG_THRESHOLD  10  static void  psh2_hint_table_find_strong_point( PSH2_Hint_Table  table,                                     PSH2_Point       point,                                     FT_Int           major_dir )  {    PSH2_Hint*   sort      = table->sort;    FT_UInt      num_hints = table->num_hints;    for ( ; num_hints > 0; num_hints--, sort++ )    {      PSH2_Hint  hint = sort[0];      if ( ABS( point->dir_in )  == major_dir ||           ABS( point->dir_out ) == major_dir )      {        FT_Pos  d;        d = point->org_u - hint->org_pos;        if ( ABS( d ) < PSH2_STRONG_THRESHOLD )        {        Is_Strong:          psh2_point_set_strong( point );          point->hint = hint;          break;        }        d -= hint->org_len;        if ( ABS( d ) < PSH2_STRONG_THRESHOLD )          goto Is_Strong;      }#if 1      if ( point->org_u >= hint->org_pos &&           point->org_u <= hint->org_pos + hint->org_len &&           psh2_point_is_extremum( point ) )      {        /* attach to hint, but don't mark as strong */        point->hint = hint;        break;      }#endif    }  }  /* find strong points in a glyph */  static void  psh2_glyph_find_strong_points( PSH2_Glyph  glyph,                                 FT_Int      dimension )  {    /* a point is strong if it is located on a stem                   */    /* edge and has an "in" or "out" tangent to the hint's direction  */    {      PSH2_Hint_Table  table     = &glyph->hint_tables[dimension];      PS_Mask          mask      = table->hint_masks->masks;      FT_UInt          num_masks = table->hint_masks->num_masks;      FT_UInt          first     = 0;      FT_Int           major_dir = dimension == 0 ? PSH2_DIR_UP : PSH2_DIR_RIGHT;      /* process secondary hints to "selected" points */      if ( num_masks > 1 )      {        mask++;        for ( ; num_masks > 1; num_masks--, mask++ )        {          FT_UInt  next;          FT_Int   count;          next  = mask->end_point;          count = next - first;          if ( count > 0 )          {            PSH2_Point  point = glyph->points + first;            psh2_hint_table_activate_mask( table, mask );            for ( ; count > 0; count--, point++ )              psh2_hint_table_find_strong_point( table, point, major_dir );          }          first = next;        }      }      /* process primary hints for all points */      if ( num_masks == 1 )      {        FT_UInt     count = glyph->num_points;        PSH2_Point  point = glyph->points;        psh2_hint_table_activate_mask( table, table->hint_masks->masks );        for ( ; count > 0; count--, point++ )        {          if ( !psh2_point_is_strong( point ) )            psh2_hint_table_find_strong_point( table, point, major_dir );        }      }      /* now, certain points may have been attached to hint and */      /* not marked as strong; update their flags then          */      {        FT_UInt     count = glyph->num_points;        PSH2_Point  point = glyph->points;        for ( ; count > 0; count--, point++ )          if ( point->hint && !psh2_point_is_strong( point ) )            psh2_point_set_strong( point );      }    }  }  /* interpolate strong points with the help of hinted coordinates */  static void  psh2_glyph_interpolate_strong_points( PSH2_Glyph  glyph,                                        FT_Int      dimension )  {    PSH_Dimension    dim   = &glyph->globals->dimension[dimension];    FT_Fixed         scale = dim->scale_mult;    {      FT_UInt     count = glyph->num_points;      PSH2_Point  point = glyph->points;      for ( ; count > 0; count--, point++ )      {        PSH2_Hint  hint = point->hint;        if ( hint )        {          FT_Pos  delta;          delta = point->org_u - hint->org_pos;          if ( delta <= 0 )            point->cur_u = hint->cur_pos + FT_MulFix( delta, scale );          else if ( delta >= hint->org_len )            point->cur_u = hint->cur_pos + hint->cur_len +                           FT_MulFix( delta - hint->org_len, scale );          else if ( hint->org_len > 0 )            point->cur_u = hint->cur_pos +                           FT_MulDiv( delta, hint->cur_len, hint->org_len );          else            point->cur_u = hint->cur_pos;          psh2_point_set_fitted( point );        }      }    }  }  static void  psh2_glyph_interpolate_normal_points( PSH2_Glyph  glyph,                                        FT_Int      dimension )  {#if 1    PSH_Dimension    dim   = &glyph->globals->dimension[dimension];    FT_Fixed         scale = dim->scale_mult;    /* first technique: a point is strong if it is a local extrema */    {      FT_UInt     count = glyph->num_points;      PSH2_Point  point = glyph->points;      for ( ; count > 0; count--, point++ )      {        if ( psh2_point_is_strong( point ) )          continue;        /* sometimes, some local extremas are smooth points */        if ( psh2_point_is_smooth( point ) )        {          if ( point->dir_in == PSH2_DIR_NONE  ||               point->dir_in != point->dir_out )            continue;          if ( !psh2_point_is_extremum( point ) )            continue;          point->flags &= ~PSH2_POINT_SMOOTH;        }        /* find best enclosing point coordinates */        {          PSH2_Point  before = 0;          PSH2_Point  after  = 0;          FT_Pos      diff_before = -32000;          FT_Pos      diff_after  =  32000;          FT_Pos      u = point->org_u;          FT_Int      count2 = glyph->num_points;          PSH2_Point  cur    = glyph->points;          for ( ; count2 > 0; count2--, cur++ )          {            if ( psh2_point_is_strong( cur ) )            {              FT_Pos   diff = cur->org_u - u;;              if ( diff <= 0 )              {                if ( diff > diff_before )                {                  diff_before = diff;                  before      = cur;                }              }              else if ( diff >= 0 )              {                if ( diff < diff_after )                {                  diff_after = diff;                  after      = cur;                }              }            }          }          if ( !before )          {            if ( !after )              continue;            /* we are before the first strong point coordinate; */            /* simply translate the point                       */            point->cur_u = after->cur_u +                           FT_MulFix( point->org_u - after->org_u, scale );          }          else if ( !after )          {            /* we are after the last strong point coordinate; */            /* simply translate the point                     */            point->cur_u = before->cur_u +                           FT_MulFix( point->org_u - before->org_u, scale );          }          else          {            if ( diff_before == 0 )              point->cur_u = before->cur_u;            else if ( diff_after == 0 )              point->cur_u = after->cur_u;            else              point->cur_u = before->cur_u +                             FT_MulDiv( u - before->org_u,                                        after->cur_u - before->cur_u,                                        after->org_u - before->org_u );          }          psh2_point_set_fitted( point );        }      }    }#endif  }  /* interpolate other points */  static void  psh2_glyph_interpolate_other_points( PSH2_Glyph  glyph,                                       FT_Int      dimension )  {    PSH_Dimension dim          = &glyph->globals->dimension[dimension];    FT_Fixed      scale        = dim->scale_mult;    FT_Fixed      delta        = dim->scale_delta;    PSH2_Contour  contour      = glyph->contours;    FT_UInt       num_contours = glyph->num_contours;    for ( ; num_contours > 0; num_contours--, contour++ )    {      PSH2_Point   start = contour->start;      PSH2_Point   first, next, point;      FT_UInt      fit_count;      /* count the number of strong points in this contour */      next      = start + contour->count;      fit_count = 0;      first     = 0;      for ( point = start; point < next; point++ )        if ( psh2_point_is_fitted( point ) )        {          if ( !first )            first = point;          fit_count++;        }      /* if there are less than 2 fitted points in the contour, we */      /* simply scale and eventually translate the contour points  */      if ( fit_count < 2 )      {        if ( fit_count == 1 )          delta = first->cur_u - FT_MulFix( first->org_u, scale );        for ( point = start; point < next; point++ )          if ( point != first )            point->cur_u = FT_MulFix( point->org_u, scale ) + delta;        goto Next_Contour;      }      /* there are more than 2 strong points in this contour; we */      /* need to interpolate weak points between them            */      start = first;      do      {        point = first;        /* skip consecutive fitted points */        for (;;)        {          next = first->next;          if ( next == start )            goto Next_Contour;          if ( !psh2_point_is_fitted( next ) )            break;          first = next;        }        /* find next fitted point after unfitted one */        for (;;)        {          next = next->next;          if ( psh2_point_is_fitted( next ) )            break;        }        /* now interpolate between them */        {          FT_Pos    org_a, org_ab, cur_a, cur_ab;          FT_Pos    org_c, org_ac, cur_c;          FT_Fixed  scale_ab;          if ( first->org_u <= next->org_u )          {            org_a  = first->org_u;            cur_a  = first->cur_u;            org_ab = next->org_u - org_a;            cur_ab = next->cur_u - cur_a;          }          else          {            org_a  = next->org_u;            cur_a  = next->cur_u;            org_ab = first->org_u - org_a;            cur_ab = first->cur_u - cur_a;          }          scale_ab = 0x10000L;          if ( org_ab > 0 )            scale_ab = FT_DivFix( cur_ab, org_ab );          point = first->next;          do          {            org_c  = point->org_u;            org_ac = org_c - org_a;            if ( org_ac <= 0 )            {              /* on the left of the interpolation zone */              cur_c = cur_a + FT_MulFix( org_ac, scale );            }            else if ( org_ac >= org_ab )            {              /* on the right on the interpolation zone */              cur_c = cur_a + cur_ab + FT_MulFix( org_ac - org_ab, scale );            }            else            {              /* within the interpolation zone */              cur_c = cur_a + FT_MulFix( org_ac, scale_ab );            }            point->cur_u = cur_c;            point = point->next;          } while ( point != next );        }        /* keep going until all points in the contours have been processed */        first = next;      } while ( first != start );    Next_Contour:      ;    }  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                     HIGH-LEVEL INTERFACE                      *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  FT_Error  ps2_hints_apply( PS_Hints     ps_hints,                   FT_Outline*  outline,                   PSH_Globals  globals )  {    PSH2_GlyphRec  glyphrec;    PSH2_Glyph     glyph = &glyphrec;    FT_Error       error;#ifdef DEBUG_HINTER    FT_Memory      memory;#endif    FT_Int         dimension;#ifdef DEBUG_HINTER    memory = globals->memory;    if ( ps2_debug_glyph )    {      psh2_glyph_done( ps2_debug_glyph );      FT_FREE( ps2_debug_glyph );    }    if ( FT_NEW( glyph ) )      return error;    ps2_debug_glyph = glyph;#endif    error = psh2_glyph_init( glyph, outline, ps_hints, globals );    if ( error )      goto Exit;    for ( dimension = 0; dimension < 2; dimension++ )    {      /* load outline coordinates into glyph */      psh2_glyph_load_points( glyph, dimension );      /* compute aligned stem/hints positions */      psh2_hint_table_align_hints( &glyph->hint_tables[dimension],                                   glyph->globals,                                   dimension );      /* find strong points, align them, then interpolate others */      psh2_glyph_find_strong_points( glyph, dimension );      psh2_glyph_interpolate_strong_points( glyph, dimension );      psh2_glyph_interpolate_normal_points( glyph, dimension );      psh2_glyph_interpolate_other_points( glyph, dimension );      /* save hinted coordinates back to outline */      psh2_glyph_save_points( glyph, dimension );    }  Exit:#ifndef DEBUG_HINTER    psh2_glyph_done( glyph );#endif    return error;  }/* END */

⌨️ 快捷键说明

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