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

📄 ahhint.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
              {                /* we are on the edge */                u = edge->pos;                goto Store_Point;              }            }            {              AH_Edge  before = edges + min - 1;              AH_Edge  after  = edges + min + 0;              /* assert( before && after && before != after ) */              if ( before->scale == 0 )                before->scale = FT_DivFix( after->pos - before->pos,                                           after->fpos - before->fpos );              u = before->pos + FT_MulFix( fu - before->fpos,                                           before->scale );            }          }#else /* !0 */          /* otherwise, interpolate the point in between */          {            AH_Edge  before = 0;            AH_Edge  after  = 0;            for ( edge = edges; edge < edge_limit; edge++ )            {              if ( u == edge->fpos )              {                u = edge->pos;                goto Store_Point;              }              if ( u < edge->fpos )                break;              before = edge;            }            for ( edge = edge_limit - 1; edge >= edges; edge-- )            {              if ( u == edge->fpos )              {                u = edge->pos;                goto Store_Point;              }              if ( u > edge->fpos )                break;              after = edge;            }            if ( before->scale == 0 )              before->scale = FT_DivFix( after->pos - before->pos,                                        after->fpos - before->fpos );            u = before->pos + FT_MulFix( fu - before->fpos,                                        before->scale );          }#endif /* !0 */        Store_Point:          /* save the point position */          if ( dimension )            point->y = u;          else            point->x = u;          point->flags |= touch_flag;        }      edges      = outline->vert_edges;      edge_limit = edges + outline->num_vedges;      touch_flag = AH_FLAG_TOUCH_X;    }  }#ifndef AH_OPTION_NO_WEAK_INTERPOLATION  static void  ah_iup_shift( AH_Point  p1,                AH_Point  p2,                AH_Point  ref )  {    AH_Point  p;    FT_Pos    delta = ref->u - ref->v;    for ( p = p1; p < ref; p++ )      p->u = p->v + delta;    for ( p = ref + 1; p <= p2; p++ )      p->u = p->v + delta;  }  static void  ah_iup_interp( AH_Point  p1,                 AH_Point  p2,                 AH_Point  ref1,                 AH_Point  ref2 )  {    AH_Point  p;    FT_Pos    u;    FT_Pos    v1 = ref1->v;    FT_Pos    v2 = ref2->v;    FT_Pos    d1 = ref1->u - v1;    FT_Pos    d2 = ref2->u - v2;    if ( p1 > p2 )      return;    if ( v1 == v2 )    {      for ( p = p1; p <= p2; p++ )      {        u = p->v;        if ( u <= v1 )          u += d1;        else          u += d2;        p->u = u;      }      return;    }    if ( v1 < v2 )    {      for ( p = p1; p <= p2; p++ )      {        u = p->v;        if ( u <= v1 )          u += d1;        else if ( u >= v2 )          u += d2;        else          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );        p->u = u;      }    }    else    {      for ( p = p1; p <= p2; p++ )      {        u = p->v;        if ( u <= v2 )          u += d2;        else if ( u >= v1 )          u += d1;        else          u = ref1->u + FT_MulDiv( u - v1, ref2->u - ref1->u, v2 - v1 );        p->u = u;      }    }  }  /* interpolate weak points -- this is equivalent to the TrueType `IUP' */  /* hinting instruction                                                 */  static void  ah_hinter_align_weak_points( AH_Hinter  hinter )  {    AH_Outline  outline = hinter->glyph;    FT_Int      dimension;    AH_Point    points;    AH_Point    point_limit;    AH_Point*   contour_limit;    AH_Flags    touch_flag;    points      = outline->points;    point_limit = points + outline->num_points;    /* PASS 1: Move segment points to edge positions */    touch_flag = AH_FLAG_TOUCH_Y;    contour_limit = outline->contours + outline->num_contours;    ah_setup_uv( outline, AH_UV_OY );    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Point   point;      AH_Point   end_point;      AH_Point   first_point;      AH_Point*  contour;      point   = points;      contour = outline->contours;      for ( ; contour < contour_limit; contour++ )      {        point       = *contour;        end_point   = point->prev;        first_point = point;        while ( point <= end_point && !( point->flags & touch_flag ) )          point++;        if ( point <= end_point )        {          AH_Point  first_touched = point;          AH_Point  cur_touched   = point;          point++;          while ( point <= end_point )          {            if ( point->flags & touch_flag )            {              /* we found two successive touched points; we interpolate */              /* all contour points between them                        */              ah_iup_interp( cur_touched + 1, point - 1,                             cur_touched, point );              cur_touched = point;            }            point++;          }          if ( cur_touched == first_touched )          {            /* this is a special case: only one point was touched in the */            /* contour; we thus simply shift the whole contour           */            ah_iup_shift( first_point, end_point, cur_touched );          }          else          {            /* now interpolate after the last touched point to the end */            /* of the contour                                          */            ah_iup_interp( cur_touched + 1, end_point,                           cur_touched, first_touched );            /* if the first contour point isn't touched, interpolate */            /* from the contour start to the first touched point     */            if ( first_touched > points )              ah_iup_interp( first_point, first_touched - 1,                             cur_touched, first_touched );          }        }      }      /* now save the interpolated values back to x/y */      if ( dimension )      {        for ( point = points; point < point_limit; point++ )          point->y = point->u;        touch_flag = AH_FLAG_TOUCH_X;        ah_setup_uv( outline, AH_UV_OX );      }      else      {        for ( point = points; point < point_limit; point++ )          point->x = point->u;        break;  /* exit loop */      }    }  }#endif /* !AH_OPTION_NO_WEAK_INTERPOLATION */  FT_LOCAL_DEF( void )  ah_hinter_align_points( AH_Hinter  hinter )  {    ah_hinter_align_edge_points( hinter );#ifndef AH_OPTION_NO_STRONG_INTERPOLATION    ah_hinter_align_strong_points( hinter );#endif#ifndef AH_OPTION_NO_WEAK_INTERPOLATION    ah_hinter_align_weak_points( hinter );#endif  }  /*************************************************************************/  /*************************************************************************/  /*************************************************************************/  /****                                                                 ****/  /****       H I N T E R   O B J E C T   M E T H O D S                 ****/  /****                                                                 ****/  /*************************************************************************/  /*************************************************************************/  /*************************************************************************/  /* scale and fit the global metrics */  static void  ah_hinter_scale_globals( AH_Hinter  hinter,                           FT_Fixed   x_scale,                           FT_Fixed   y_scale )  {    FT_Int           n;    AH_Face_Globals  globals = hinter->globals;    AH_Globals       design  = &globals->design;    AH_Globals       scaled  = &globals->scaled;    /* copy content */    *scaled = *design;    /* scale the standard widths & heights */    for ( n = 0; n < design->num_widths; n++ )      scaled->widths[n] = FT_MulFix( design->widths[n], x_scale );    for ( n = 0; n < design->num_heights; n++ )      scaled->heights[n] = FT_MulFix( design->heights[n], y_scale );    scaled->stds[0] = ( design->num_widths  > 0 ) ? scaled->widths[0]  : 32000;    scaled->stds[1] = ( design->num_heights > 0 ) ? scaled->heights[0] : 32000;    /* scale the blue zones */    for ( n = 0; n < AH_BLUE_MAX; n++ )    {      FT_Pos  delta, delta2;      delta = design->blue_shoots[n] - design->blue_refs[n];      delta2 = delta;      if ( delta < 0 )        delta2 = -delta2;      delta2 = FT_MulFix( delta2, y_scale );      if ( delta2 < 32 )        delta2 = 0;      else if ( delta2 < 64 )        delta2 = 32 + ( ( ( delta2 - 32 ) + 16 ) & -32 );      else        delta2 = ( delta2 + 32 ) & -64;      if ( delta < 0 )        delta2 = -delta2;      scaled->blue_refs[n] =        ( FT_MulFix( design->blue_refs[n], y_scale ) + 32 ) & -64;      scaled->blue_shoots[n] = scaled->blue_refs[n] + delta2;    }    globals->x_scale = x_scale;    globals->y_scale = y_scale;  }  static void  ah_hinter_align( AH_Hinter  hinter )  {    ah_hinter_align_edge_points( hinter );    ah_hinter_align_points( hinter );  }  /* finalize a hinter object */  FT_LOCAL_DEF( void )  ah_hinter_done( AH_Hinter  hinter )  {    if ( hinter )    {      FT_Memory  memory = hinter->memory;      ah_loader_done( hinter->loader );      ah_outline_done( hinter->glyph );      /* note: the `globals' pointer is _not_ owned by the hinter */      /*       but by the current face object; we don't need to   */      /*       release it                                         */      hinter->globals = 0;      hinter->face    = 0;      FT_FREE( hinter );    }  }  /* create a new empty hinter object */  FT_LOCAL_DEF( FT_Error )  ah_hinter_new( FT_Library  library,                 AH_Hinter  *ahinter )  {    AH_Hinter  hinter = 0;    FT_Memory  memory = library->memory;    FT_Error   error;    *ahinter = 0;    /* allocate object */    if ( FT_NEW( hinter ) )      goto Exit;    hinter->memory = memory;    hinter->flags  = 0;    /* allocate outline and loader */    error = ah_outline_new( memory, &hinter->glyph )  ||            ah_loader_new ( memory, &hinter->loader ) ||            ah_loader_create_extra( hinter->loader );    if ( error )      goto Exit;    *ahinter = hinter;  Exit:    if ( error )      ah_hinter_done( hinter );    return error;  }  /* create a face's autohint globals */  FT_LOCAL_DEF( FT_Error )  ah_hinter_new_face_globals( AH_Hinter   hinter,                              FT_Face     face,                              AH_Globals  globals )  {    FT_Error         error;    FT_Memory        memory = hinter->memory;    AH_Face_Globals  face_globals;    if ( FT_NEW( face_globals ) )      goto Exit;    hinter->face    = face;    hinter->globals = face_globals;    if ( globals )      face_globals->design = *globals;    else      ah_hinter_compute_globals( hinter );    face->autohint.data      = face_globals;    face->autohint.finalizer = (FT_Generic_Finalizer)                                 ah_hinter_done_face_globals;    face_globals->face       = face;  Exit:    return error;  }  /* discard a face's autohint globals */  FT_LOCAL_DEF( void )  ah_hinter_done_face_globals( AH_Face_Globals  globals )  {    FT_Face    face   = globals->face;    FT_Memory  memory = face->memory;    FT_FREE( globals );  }  static FT_Error  ah_hinter_load( AH_Hinter  hinter,                  FT_UInt    glyph_index,                  FT_Int32   load_flags,                  FT_UInt    depth )  {    FT_Face           face     = hinter->face;    FT_GlyphSlot      slot     = face->glyph;

⌨️ 快捷键说明

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