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

📄 pshalgo.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
          if ( parent )          {            FT_Pos  par_org_center, par_cur_center;            FT_Pos  cur_org_center, cur_delta;            /* ensure that parent is already fitted */            if ( !psh_hint_is_fitted( parent ) )              psh_hint_align( parent, globals, dimension, glyph );            par_org_center = parent->org_pos + ( parent->org_len >> 1 );            par_cur_center = parent->cur_pos + ( parent->cur_len >> 1 );            cur_org_center = hint->org_pos   + ( hint->org_len   >> 1 );            cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );            pos       = par_cur_center + cur_delta - ( len >> 1 );          }          hint->cur_pos = pos;          hint->cur_len = fit_len;          /* Stem adjustment tries to snap stem widths to standard           * ones.  This is important to prevent unpleasant rounding           * artefacts.           */          if ( glyph->do_stem_adjust )          {            if ( len <= 64 )            {              /* the stem is less than one pixel; we will center it               * around the nearest pixel center               */#if 1              pos = ( pos + ( len >> 1 ) ) & -64;#else             /* this seems to be a bug! */              pos = ( pos + ( ( len >> 1 ) & -64 ) );#endif              len = 64;            }            else            {              len = psh_dimension_quantize_len( dim, len, 0 );            }          }          /* now that we have a good hinted stem width, try to position */          /* the stem along a pixel grid integer coordinate             */          hint->cur_pos = pos + psh_hint_snap_stem_side_delta( pos, len );          hint->cur_len = len;        }      }      if ( do_snapping )      {        pos = hint->cur_pos;        len = hint->cur_len;        if ( len < 64 )          len = 64;        else          len = ( len + 32 ) & -64;        switch ( align.align )        {          case PSH_BLUE_ALIGN_TOP:            hint->cur_pos = align.align_top - len;            hint->cur_len = len;            break;          case PSH_BLUE_ALIGN_BOT:            hint->cur_len = len;            break;          case PSH_BLUE_ALIGN_BOT | PSH_BLUE_ALIGN_TOP:            /* don't touch */            break;          default:            hint->cur_len = len;            if ( len & 64 )              pos = ( ( pos + ( len >> 1 ) ) & -64 ) + 32;            else              pos = ( pos + ( len >> 1 ) + 32 ) & -64;            hint->cur_pos = pos - ( len >> 1 );            hint->cur_len = len;        }      }      psh_hint_set_fitted( hint );#ifdef DEBUG_HINTER      if ( ps_debug_hint_func )        ps_debug_hint_func( hint, dimension );#endif    }  }#if 0  /* not used for now, experimental */ /*  *  A variant to perform "light" hinting (i.e. FT_RENDER_MODE_LIGHT)  *  of stems  */  static void  psh_hint_align_light( PSH_Hint     hint,                        PSH_Globals  globals,                        FT_Int       dimension,                        PSH_Glyph    glyph )  {    PSH_Dimension  dim   = &globals->dimension[dimension];    FT_Fixed       scale = dim->scale_mult;    FT_Fixed       delta = dim->scale_delta;    if ( !psh_hint_is_fitted( hint ) )    {      FT_Pos  pos = FT_MulFix( hint->org_pos, scale ) + delta;      FT_Pos  len = FT_MulFix( hint->org_len, scale );      FT_Pos  fit_len;      PSH_AlignmentRec  align;      /* ignore stem alignments when requested through the hint flags */      if ( ( dimension == 0 && !glyph->do_horz_hints ) ||           ( dimension == 1 && !glyph->do_vert_hints ) )      {        hint->cur_pos = pos;        hint->cur_len = len;        psh_hint_set_fitted( hint );        return;      }      fit_len = len;      hint->cur_len = fit_len;      /* check blue zones for horizontal stems */      align.align = PSH_BLUE_ALIGN_NONE;      align.align_bot = align.align_top = 0;      if ( dimension == 1 )        psh_blues_snap_stem( &globals->blues,                             hint->org_pos + hint->org_len,                             hint->org_pos,                             &align );      switch ( align.align )      {      case PSH_BLUE_ALIGN_TOP:        /* the top of the stem is aligned against a blue zone */        hint->cur_pos = align.align_top - fit_len;        break;      case PSH_BLUE_ALIGN_BOT:        /* the bottom of the stem is aligned against a blue zone */        hint->cur_pos = align.align_bot;        break;      case PSH_BLUE_ALIGN_TOP | PSH_BLUE_ALIGN_BOT:        /* both edges of the stem are aligned against blue zones */        hint->cur_pos = align.align_bot;        hint->cur_len = align.align_top - align.align_bot;        break;      default:        {          PSH_Hint  parent = hint->parent;          if ( parent )          {            FT_Pos  par_org_center, par_cur_center;            FT_Pos  cur_org_center, cur_delta;            /* ensure that parent is already fitted */            if ( !psh_hint_is_fitted( parent ) )              psh_hint_align_light( parent, globals, dimension, glyph );            par_org_center = parent->org_pos + ( parent->org_len / 2 );            par_cur_center = parent->cur_pos + ( parent->cur_len / 2 );            cur_org_center = hint->org_pos   + ( hint->org_len   / 2 );            cur_delta = FT_MulFix( cur_org_center - par_org_center, scale );            pos       = par_cur_center + cur_delta - ( len >> 1 );          }          /* Stems less than one pixel wide are easy -- we want to           * make them as dark as possible, so they must fall within           * one pixel.  If the stem is split between two pixels           * then snap the edge that is nearer to the pixel boundary           * to the pixel boundary.           */          if ( len <= 64 )          {            if ( ( pos + len + 63 ) / 64  != pos / 64 + 1 )              pos += psh_hint_snap_stem_side_delta ( pos, len );          }          /* Position stems other to minimize the amount of mid-grays.           * There are, in general, two positions that do this,           * illustrated as A) and B) below.           *           *   +                   +                   +                   +           *           * A)             |--------------------------------|           * B)   |--------------------------------|           * C)       |--------------------------------|           *           * Position A) (split the excess stem equally) should be better           * for stems of width N + f where f < 0.5.           *           * Position B) (split the deficiency equally) should be better           * for stems of width N + f where f > 0.5.           *           * It turns out though that minimizing the total number of lit           * pixels is also important, so position C), with one edge           * aligned with a pixel boundary is actually preferable           * to A).  There are also more possibile positions for C) than           * for A) or B), so it involves less distortion of the overall           * character shape.           */          else /* len > 64 */          {            FT_Fixed  frac_len = len & 63;            FT_Fixed  center = pos + ( len >> 1 );            FT_Fixed  delta_a, delta_b;            if ( ( len / 64 ) & 1 )            {              delta_a = ( center & -64 ) + 32 - center;              delta_b = ( ( center + 32 ) & - 64 ) - center;            }            else            {              delta_a = ( ( center + 32 ) & - 64 ) - center;              delta_b = ( center & -64 ) + 32 - center;            }            /* We choose between B) and C) above based on the amount             * of fractinal stem width; for small amounts, choose             * C) always, for large amounts, B) always, and inbetween,             * pick whichever one involves less stem movement.             */            if ( frac_len < 32 )            {              pos += psh_hint_snap_stem_side_delta ( pos, len );            }            else if ( frac_len < 48 )            {              FT_Fixed  side_delta = psh_hint_snap_stem_side_delta ( pos,                                                                     len );              if ( ABS( side_delta ) < ABS( delta_b ) )                pos += side_delta;              else                pos += delta_b;            }            else            {              pos += delta_b;            }          }          hint->cur_pos = pos;        }      }  /* switch */      psh_hint_set_fitted( hint );#ifdef DEBUG_HINTER      if ( ps_debug_hint_func )        ps_debug_hint_func( hint, dimension );#endif    }  }#endif /* 0 */  static void  psh_hint_table_align_hints( PSH_Hint_Table  table,                              PSH_Globals     globals,                              FT_Int          dimension,                              PSH_Glyph       glyph )  {    PSH_Hint       hint;    FT_UInt        count;#ifdef DEBUG_HINTER    PSH_Dimension  dim   = &globals->dimension[dimension];    FT_Fixed       scale = dim->scale_mult;    FT_Fixed       delta = dim->scale_delta;    if ( ps_debug_no_vert_hints && dimension == 0 )    {      ps_simple_scale( table, scale, delta, dimension );      return;    }    if ( ps_debug_no_horz_hints && dimension == 1 )    {      ps_simple_scale( table, scale, delta, dimension );      return;    }#endif /* DEBUG_HINTER*/    hint  = table->hints;    count = table->max_hints;    for ( ; count > 0; count--, hint++ )      psh_hint_align( hint, globals, dimension, glyph );  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                POINTS INTERPOLATION ROUTINES                  *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/#define PSH_ZONE_MIN  -3200000L#define PSH_ZONE_MAX  +3200000L#define xxDEBUG_ZONES#ifdef DEBUG_ZONES#include <stdio.h>  static void  psh_print_zone( PSH_Zone  zone )  {    printf( "zone [scale,delta,min,max] = [%.3f,%.3f,%d,%d]\n",             zone->scale / 65536.0,             zone->delta / 64.0,             zone->min,             zone->max );  }#else#define psh_print_zone( x )  do { } while ( 0 )#endif /* DEBUG_ZONES */  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****                    HINTER GLYPH MANAGEMENT                    *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/#ifdef COMPUTE_INFLEXS  /* compute all inflex points in a given glyph */  static void  psh_glyph_compute_inflections( PSH_Glyph  glyph )  {    FT_UInt  n;    for ( n = 0; n < glyph->num_contours; n++ )    {      PSH_Point  first, start, end, before, after;      FT_Angle   angle_in, angle_seg, angle_out;      FT_Angle   diff_in, diff_out;      FT_Int     finished = 0;      /* we need at least 4 points to create an inflection point */      if ( glyph->contours[n].count < 4 )        continue;      /* compute first segment in contour */      first = glyph->contours[n].start;      start = end = first;      do      {        end = end->next;        if ( end == first )          goto Skip;      } while ( PSH_POINT_EQUAL_ORG( end, first ) );      angle_seg = PSH_POINT_ANGLE( start, end );      /* extend the segment start whenever possible */      before = start;      do      {        do        {          start  = before;          before = before->prev;          if ( before == first )            goto Skip;        } while ( PSH_POINT_EQUAL_ORG( before, start ) );        angle_in = PSH_POINT_ANGLE( before, start );      } while ( angle_in == angle_seg );      first   = start;      diff_in = FT_Angle_Diff( angle_in, angle_seg );      /* now, process all segments in the contour */      do      {        /* first, extend current segment's end whenever possible */        after = end;        do        {          do          {            end   = after;            after = after->next;            if ( after == first )              finished = 1;          } while ( PSH_POINT_EQUAL_ORG( end, after ) );          angle_out = PSH_POINT_ANGLE( end, after );        } while ( angle_out == angle_seg );        diff_out = FT_Angle_Diff( angle_seg, angle_out );        if ( ( diff_in ^ diff_out ) < 0 )        {          /* diff_in and diff_out have different signs, we have */          /* inflection points here...                          */          do          {            psh_point_set_inflex( start );            start = start->next;          }          while ( start != end );          psh_point_set_inflex( start );        }        start     = end;        end       = after;        angle_seg = angle_out;        diff_in   = diff_out;      } while ( !finished );    Skip:      ;    }  }#endif /* COMPUTE_INFLEXS */  static void  psh_glyph_done( PSH_Glyph  glyph )  {    FT_Memory  memory = glyph->memory;    psh_hint_table_done( &glyph->hint_tables[1], memory );    psh_hint_table_done( &glyph->hint_tables[0], memory );    FT_FREE( glyph->points );    FT_FREE( glyph->contours );    glyph->num_points   = 0;    glyph->num_contours = 0;    glyph->memory = 0;  }  static int  psh_compute_dir( FT_Pos  dx,                   FT_Pos  dy )

⌨️ 快捷键说明

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