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

📄 pshalgo.c

📁 奇趣公司比较新的qt/emd版本
💻 C
📖 第 1 页 / 共 4 页
字号:
      FT_UInt    count = glyph->num_points;      PSH_Point  point = glyph->points;      psh_hint_table_activate_mask( table, table->hint_masks->masks );      psh_hint_table_find_strong_points( table, point, count,                                         threshold, major_dir );    }    /* now, certain points may have been attached to a 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 );    }  }  /* find points in a glyph which are in a blue zone and have `in' or */  /* `out' tangents parallel to the horizontal axis                   */  static void  psh_glyph_find_blue_points( PSH_Blues  blues,                              PSH_Glyph  glyph )  {    PSH_Blue_Table  table;    PSH_Blue_Zone   zone;    FT_UInt         glyph_count = glyph->num_points;    FT_UInt         blue_count;    PSH_Point       point = glyph->points;    for ( ; glyph_count > 0; glyph_count--, point++ )    {      FT_Pos  y;      /* check tangents */      if ( !PSH_DIR_COMPARE( point->dir_in,  PSH_DIR_HORIZONTAL ) &&           !PSH_DIR_COMPARE( point->dir_out, PSH_DIR_HORIZONTAL ) )        continue;      /* skip strong points */      if ( psh_point_is_strong( point ) )        continue;      y = point->org_u;      /* look up top zones */      table      = &blues->normal_top;      blue_count = table->count;      zone       = table->zones;      for ( ; blue_count > 0; blue_count--, zone++ )      {        FT_Pos  delta = y - zone->org_bottom;        if ( delta < -blues->blue_fuzz )          break;        if ( y <= zone->org_top + blues->blue_fuzz )          if ( blues->no_overshoots || delta <= blues->blue_threshold )          {            point->cur_u = zone->cur_bottom;            psh_point_set_strong( point );            psh_point_set_fitted( point );          }      }      /* look up bottom zones */      table      = &blues->normal_bottom;      blue_count = table->count;      zone       = table->zones + blue_count - 1;      for ( ; blue_count > 0; blue_count--, zone-- )      {        FT_Pos  delta = zone->org_top - y;        if ( delta < -blues->blue_fuzz )          break;        if ( y >= zone->org_bottom - blues->blue_fuzz )          if ( blues->no_overshoots || delta < blues->blue_threshold )          {            point->cur_u = zone->cur_top;            psh_point_set_strong( point );            psh_point_set_fitted( 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 );      }    }  }#define  PSH_MAX_STRONG_INTERNAL  16  static void  psh_glyph_interpolate_normal_points( PSH_Glyph  glyph,                                       FT_Int     dimension )  {#if 1    /* first technique: a point is strong if it is a local extremum */    PSH_Dimension  dim    = &glyph->globals->dimension[dimension];    FT_Fixed       scale  = dim->scale_mult;    FT_Memory      memory = glyph->memory;    PSH_Point*     strongs     = NULL;    PSH_Point      strongs_0[PSH_MAX_STRONG_INTERNAL];    FT_UInt        num_strongs = 0;    PSH_Point      points = glyph->points;    PSH_Point      points_end = points + glyph->num_points;    PSH_Point      point;    /* first count the number of strong points */    for ( point = points; point < points_end; point++ )    {      if ( psh_point_is_strong( point ) )        num_strongs++;    }    if ( num_strongs == 0 )  /* nothing to do here */      return;    /* allocate an array to store a list of points, */    /* stored in increasing org_u order             */    if ( num_strongs <= PSH_MAX_STRONG_INTERNAL )      strongs = strongs_0;    else    {      FT_Error  error;      if ( FT_NEW_ARRAY( strongs, num_strongs ) )        return;    }    num_strongs = 0;    for ( point = points; point < points_end; point++ )    {      PSH_Point*  insert;      if ( !psh_point_is_strong( point ) )        continue;      for ( insert = strongs + num_strongs; insert > strongs; insert-- )      {        if ( insert[-1]->org_u <= point->org_u )          break;        insert[0] = insert[-1];      }      insert[0] = point;      num_strongs++;    }    /* now try to interpolate all normal points */    for ( point = points; point < points_end; point++ )    {      if ( psh_point_is_strong( point ) )        continue;      /* sometimes, some local extrema 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 then interpolate */      {        PSH_Point   before, after;        FT_UInt     nn;        for ( nn = 0; nn < num_strongs; nn++ )          if ( strongs[nn]->org_u > point->org_u )            break;        if ( nn == 0 )  /* point before the first strong point */        {          after = strongs[0];          point->cur_u = after->cur_u +                           FT_MulFix( point->org_u - after->org_u,                                      scale );        }        else        {          before = strongs[nn - 1];          for ( nn = num_strongs; nn > 0; nn-- )            if ( strongs[nn - 1]->org_u < point->org_u )              break;          if ( nn == num_strongs )  /* point is after last strong point */          {            before = strongs[nn - 1];            point->cur_u = before->cur_u +                             FT_MulFix( point->org_u - before->org_u,                                        scale );          }          else          {            FT_Pos  u;            after = strongs[nn];            /* now interpolate point between before and after */            u = point->org_u;            if ( u == before->org_u )              point->cur_u = before->cur_u;            else if ( u == after->org_u )              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 );      }    }    if ( strongs != strongs_0 )      FT_FREE( strongs );#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 = FT_PIX_ROUND( scaled );      if ( fitted != 0 && 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 );      if ( dimension == 1 )        psh_glyph_find_blue_points( &globals->blues, glyph );      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 + -