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

📄 pshalgo.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
      FT_Int          major_dir = dimension == 0 ? PSH_DIR_VERTICAL                                                 : PSH_DIR_HORIZONTAL;      /* process secondary hints to "selected" points */      if ( num_masks > 1 && glyph->num_points > 0 )      {        first = mask->end_point;        mask++;        for ( ; num_masks > 1; num_masks--, mask++ )        {          FT_UInt  next;          FT_Int   count;          next  = mask->end_point;          count = next - first;          if ( count > 0 )          {            PSH_Point  point = glyph->points + first;            psh_hint_table_activate_mask( table, mask );            for ( ; count > 0; count--, point++ )              psh_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;        PSH_Point  point = glyph->points;        psh_hint_table_activate_mask( table, table->hint_masks->masks );        for ( ; count > 0; count--, point++ )        {          if ( !psh_point_is_strong( point ) )            psh_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;        PSH_Point  point = glyph->points;        for ( ; count > 0; count--, point++ )          if ( point->hint && !psh_point_is_strong( point ) )            psh_point_set_strong( point );      }    }  }  /* interpolate strong points with the help of hinted coordinates */  static void  psh_glyph_interpolate_strong_points( PSH_Glyph  glyph,                                       FT_Int     dimension )  {    PSH_Dimension  dim   = &glyph->globals->dimension[dimension];    FT_Fixed       scale = dim->scale_mult;    {      FT_UInt    count = glyph->num_points;      PSH_Point  point = glyph->points;      for ( ; count > 0; count--, point++ )      {        PSH_Hint  hint = point->hint;        if ( hint )        {          FT_Pos  delta;          if ( psh_point_is_edge_min( point ) )          {            point->cur_u = hint->cur_pos;          }          else if ( psh_point_is_edge_max( point ) )          {            point->cur_u = hint->cur_pos + hint->cur_len;          }          else          {            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;          }          psh_point_set_fitted( point );        }      }    }  }  static void  psh_glyph_interpolate_normal_points( PSH_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;      PSH_Point  point = glyph->points;      for ( ; count > 0; count--, point++ )      {        if ( psh_point_is_strong( point ) )          continue;        /* sometimes, some local extremas are smooth points */        if ( psh_point_is_smooth( point ) )        {          if ( point->dir_in == PSH_DIR_NONE   ||               point->dir_in != point->dir_out )            continue;          if ( !psh_point_is_extremum( point )   &&               !psh_point_is_inflex( point ) )            continue;          point->flags &= ~PSH_POINT_SMOOTH;        }        /* find best enclosing point coordinates */        {          PSH_Point  before = 0;          PSH_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;          PSH_Point  cur    = glyph->points;          for ( ; count2 > 0; count2--, cur++ )          {            if ( psh_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 );          }          psh_point_set_fitted( point );        }      }    }#endif /* 1 */  }  /* interpolate other points */  static void  psh_glyph_interpolate_other_points( PSH_Glyph  glyph,                                      FT_Int     dimension )  {    PSH_Dimension  dim          = &glyph->globals->dimension[dimension];    FT_Fixed       scale        = dim->scale_mult;    FT_Fixed       delta        = dim->scale_delta;    PSH_Contour    contour      = glyph->contours;    FT_UInt        num_contours = glyph->num_contours;    for ( ; num_contours > 0; num_contours--, contour++ )    {      PSH_Point  start = contour->start;      PSH_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 ( psh_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 ( !psh_point_is_fitted( next ) )            break;          first = next;        }        /* find next fitted point after unfitted one */        for (;;)        {          next = next->next;          if ( psh_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  ps_hints_apply( PS_Hints        ps_hints,                  FT_Outline*     outline,                  PSH_Globals     globals,                  FT_Render_Mode  hint_mode )  {    PSH_GlyphRec  glyphrec;    PSH_Glyph     glyph = &glyphrec;    FT_Error      error;#ifdef DEBUG_HINTER    FT_Memory     memory;#endif    FT_Int        dimension;    /* something to do? */    if ( outline->n_points == 0 || outline->n_contours == 0 )      return PSH_Err_Ok;#ifdef DEBUG_HINTER    memory = globals->memory;    if ( ps_debug_glyph )    {      psh_glyph_done( ps_debug_glyph );      FT_FREE( ps_debug_glyph );    }    if ( FT_NEW( glyph ) )      return error;    ps_debug_glyph = glyph;#endif /* DEBUG_HINTER */    error = psh_glyph_init( glyph, outline, ps_hints, globals );    if ( error )      goto Exit;    /* try to optimize the y_scale so that the top of non-capital letters     * is aligned on a pixel boundary whenever possible     */    {      PSH_Dimension  dim_x = &glyph->globals->dimension[0];      PSH_Dimension  dim_y = &glyph->globals->dimension[1];      FT_Fixed x_scale = dim_x->scale_mult;      FT_Fixed y_scale = dim_y->scale_mult;      FT_Fixed scaled;      FT_Fixed fitted;      scaled = FT_MulFix( globals->blues.normal_top.zones->org_ref, y_scale );      fitted = ( scaled + 32 ) & -64;      if (scaled != fitted ) {        y_scale = FT_MulDiv( y_scale, fitted, scaled );        if ( fitted < scaled )          x_scale -= x_scale / 50;        psh_globals_set_scale( glyph->globals, x_scale, y_scale, 0, 0 );      }    }    glyph->do_horz_hints = 1;    glyph->do_vert_hints = 1;    glyph->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||                                       hint_mode == FT_RENDER_MODE_LCD  );    glyph->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO  ||                                       hint_mode == FT_RENDER_MODE_LCD_V );    glyph->do_stem_adjust   = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );    for ( dimension = 0; dimension < 2; dimension++ )    {      /* load outline coordinates into glyph */      psh_glyph_load_points( glyph, dimension );      /* compute local extrema */      psh_glyph_compute_extrema( glyph );      /* compute aligned stem/hints positions */      psh_hint_table_align_hints( &glyph->hint_tables[dimension],                                  glyph->globals,                                  dimension,                                  glyph );      /* find strong points, align them, then interpolate others */      psh_glyph_find_strong_points( glyph, dimension );      psh_glyph_interpolate_strong_points( glyph, dimension );      psh_glyph_interpolate_normal_points( glyph, dimension );      psh_glyph_interpolate_other_points( glyph, dimension );      /* save hinted coordinates back to outline */      psh_glyph_save_points( glyph, dimension );    }  Exit:#ifndef DEBUG_HINTER    psh_glyph_done( glyph );#endif    return error;  }/* END */

⌨️ 快捷键说明

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