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

📄 ahhint.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    FT_Slot_Internal  internal = slot->internal;    FT_Fixed          x_scale  = hinter->globals->x_scale;    FT_Fixed          y_scale  = hinter->globals->y_scale;    FT_Error          error;    AH_Outline        outline  = hinter->glyph;    AH_Loader         gloader  = hinter->loader;    /* load the glyph */    error = FT_Load_Glyph( face, glyph_index, load_flags );    if ( error )      goto Exit;    /* Set `hinter->transformed' after loading with FT_LOAD_NO_RECURSE. */    hinter->transformed = internal->glyph_transformed;    if ( hinter->transformed )    {      FT_Matrix  imatrix;      imatrix              = internal->glyph_matrix;      hinter->trans_delta  = internal->glyph_delta;      hinter->trans_matrix = imatrix;      FT_Matrix_Invert( &imatrix );      FT_Vector_Transform( &hinter->trans_delta, &imatrix );    }    /* set linear horizontal metrics */    slot->linearHoriAdvance = slot->metrics.horiAdvance;    slot->linearVertAdvance = slot->metrics.vertAdvance;    switch ( slot->format )    {    case FT_GLYPH_FORMAT_OUTLINE:      /* translate glyph outline if we need to */      if ( hinter->transformed )      {        FT_UInt     n     = slot->outline.n_points;        FT_Vector*  point = slot->outline.points;        for ( ; n > 0; point++, n-- )        {          point->x += hinter->trans_delta.x;          point->y += hinter->trans_delta.y;        }      }      /* copy the outline points in the loader's current               */      /* extra points which is used to keep original glyph coordinates */      error = ah_loader_check_points( gloader, slot->outline.n_points + 2,                                      slot->outline.n_contours );      if ( error )        goto Exit;      FT_MEM_COPY( gloader->current.extra_points, slot->outline.points,                   slot->outline.n_points * sizeof ( FT_Vector ) );      FT_MEM_COPY( gloader->current.outline.contours, slot->outline.contours,                   slot->outline.n_contours * sizeof ( short ) );      FT_MEM_COPY( gloader->current.outline.tags, slot->outline.tags,                   slot->outline.n_points * sizeof ( char ) );      gloader->current.outline.n_points   = slot->outline.n_points;      gloader->current.outline.n_contours = slot->outline.n_contours;      /* compute original phantom points */      hinter->pp1.x = 0;      hinter->pp1.y = 0;      hinter->pp2.x = FT_MulFix( slot->metrics.horiAdvance, x_scale );      hinter->pp2.y = 0;      /* be sure to check for spacing glyphs */      if ( slot->outline.n_points == 0 )        goto Hint_Metrics;      /* now load the slot image into the auto-outline and run the */      /* automatic hinting process                                 */      error = ah_outline_load( outline, x_scale, y_scale, face );      if ( error )        goto Exit;      /* perform feature detection */      ah_outline_detect_features( outline );      if ( hinter->do_vert_hints )      {        ah_outline_compute_blue_edges( outline, hinter->globals );        ah_outline_scale_blue_edges( outline, hinter->globals );      }      /* perform alignment control */      ah_hinter_hint_edges( hinter );      ah_hinter_align( hinter );      /* now save the current outline into the loader's current table */      ah_outline_save( outline, gloader );      /* we now need to hint the metrics according to the change in */      /* width/positioning that occured during the hinting process  */      {        FT_Pos   old_advance, old_rsb, old_lsb, new_lsb;        AH_Edge  edge1 = outline->vert_edges;     /* leftmost edge  */        AH_Edge  edge2 = edge1 +                         outline->num_vedges - 1; /* rightmost edge */        old_advance = hinter->pp2.x;        old_rsb     = old_advance - edge2->opos;        old_lsb     = edge1->opos;        new_lsb     = edge1->pos;        hinter->pp1.x = ( ( new_lsb    - old_lsb ) + 32 ) & -64;        hinter->pp2.x = ( ( edge2->pos + old_rsb ) + 32 ) & -64;#if 0        /* try to fix certain bad advance computations */        if ( hinter->pp2.x + hinter->pp1.x == edge2->pos && old_rsb > 4 )          hinter->pp2.x += 64;#endif      }      /* good, we simply add the glyph to our loader's base */      ah_loader_add( gloader );      break;    case FT_GLYPH_FORMAT_COMPOSITE:      {        FT_UInt      nn, num_subglyphs = slot->num_subglyphs;        FT_UInt      num_base_subgs, start_point;        FT_SubGlyph  subglyph;        start_point = gloader->base.outline.n_points;        /* first of all, copy the subglyph descriptors in the glyph loader */        error = ah_loader_check_subglyphs( gloader, num_subglyphs );        if ( error )          goto Exit;        FT_MEM_COPY( gloader->current.subglyphs, slot->subglyphs,                     num_subglyphs * sizeof ( FT_SubGlyph ) );        gloader->current.num_subglyphs = num_subglyphs;        num_base_subgs = gloader->base.num_subglyphs;        /* now, read each subglyph independently */        for ( nn = 0; nn < num_subglyphs; nn++ )        {          FT_Vector  pp1, pp2;          FT_Pos     x, y;          FT_UInt    num_points, num_new_points, num_base_points;          /* gloader.current.subglyphs can change during glyph loading due */          /* to re-allocation -- we must recompute the current subglyph on */          /* each iteration                                                */          subglyph = gloader->base.subglyphs + num_base_subgs + nn;          pp1 = hinter->pp1;          pp2 = hinter->pp2;          num_base_points = gloader->base.outline.n_points;          error = ah_hinter_load( hinter, subglyph->index,                                  load_flags, depth + 1 );          if ( error )            goto Exit;          /* recompute subglyph pointer */          subglyph = gloader->base.subglyphs + num_base_subgs + nn;          if ( subglyph->flags & FT_SUBGLYPH_FLAG_USE_MY_METRICS )          {            pp1 = hinter->pp1;            pp2 = hinter->pp2;          }          else          {            hinter->pp1 = pp1;            hinter->pp2 = pp2;          }          num_points     = gloader->base.outline.n_points;          num_new_points = num_points - num_base_points;          /* now perform the transform required for this subglyph */          if ( subglyph->flags & ( FT_SUBGLYPH_FLAG_SCALE    |                                   FT_SUBGLYPH_FLAG_XY_SCALE |                                   FT_SUBGLYPH_FLAG_2X2      ) )          {            FT_Vector*  cur   = gloader->base.outline.points +                                num_base_points;            FT_Vector*  org   = gloader->base.extra_points +                                num_base_points;            FT_Vector*  limit = cur + num_new_points;            for ( ; cur < limit; cur++, org++ )            {              FT_Vector_Transform( cur, &subglyph->transform );              FT_Vector_Transform( org, &subglyph->transform );            }          }          /* apply offset */          if ( !( subglyph->flags & FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES ) )          {            FT_Int      k = subglyph->arg1;            FT_UInt     l = subglyph->arg2;            FT_Vector*  p1;            FT_Vector*  p2;            if ( start_point + k >= num_base_points         ||                               l >= (FT_UInt)num_new_points )            {              error = AH_Err_Invalid_Composite;              goto Exit;            }            l += num_base_points;            /* for now, only use the current point coordinates;    */            /* we may consider another approach in the near future */            p1 = gloader->base.outline.points + start_point + k;            p2 = gloader->base.outline.points + start_point + l;            x = p1->x - p2->x;            y = p1->y - p2->y;          }          else          {            x = FT_MulFix( subglyph->arg1, x_scale );            y = FT_MulFix( subglyph->arg2, y_scale );            x = ( x + 32 ) & -64;            y = ( y + 32 ) & -64;          }          {            FT_Outline  dummy = gloader->base.outline;            dummy.points  += num_base_points;            dummy.n_points = (short)num_new_points;            FT_Outline_Translate( &dummy, x, y );          }        }      }      break;    default:      /* we don't support other formats (yet?) */      error = AH_Err_Unimplemented_Feature;    }  Hint_Metrics:    if ( depth == 0 )    {      FT_BBox  bbox;      /* transform the hinted outline if needed */      if ( hinter->transformed )        FT_Outline_Transform( &gloader->base.outline, &hinter->trans_matrix );      /* we must translate our final outline by -pp1.x and compute */      /* the new metrics                                           */      if ( hinter->pp1.x )        FT_Outline_Translate( &gloader->base.outline, -hinter->pp1.x, 0 );      FT_Outline_Get_CBox( &gloader->base.outline, &bbox );      bbox.xMin &= -64;      bbox.yMin &= -64;      bbox.xMax  = ( bbox.xMax + 63 ) & -64;      bbox.yMax  = ( bbox.yMax + 63 ) & -64;      slot->metrics.width        = bbox.xMax - bbox.xMin;      slot->metrics.height       = bbox.yMax - bbox.yMin;      slot->metrics.horiBearingX = bbox.xMin;      slot->metrics.horiBearingY = bbox.yMax;      /* for mono-width fonts (like Andale, Courier, etc.) we need */      /* to keep the original rounded advance width                */      if ( !FT_IS_FIXED_WIDTH( slot->face ) )        slot->metrics.horiAdvance = hinter->pp2.x - hinter->pp1.x;      else        slot->metrics.horiAdvance = FT_MulFix( slot->metrics.horiAdvance,                                               x_scale );      slot->metrics.horiAdvance = ( slot->metrics.horiAdvance + 32 ) & -64;      /* now copy outline into glyph slot */      ah_loader_rewind( slot->internal->loader );      error = ah_loader_copy_points( slot->internal->loader, gloader );      if ( error )        goto Exit;      slot->outline = slot->internal->loader->base.outline;      slot->format  = FT_GLYPH_FORMAT_OUTLINE;    }#ifdef DEBUG_HINTER    ah_debug_hinter = hinter;#endif  Exit:    return error;  }  /* load and hint a given glyph */  FT_LOCAL_DEF( FT_Error )  ah_hinter_load_glyph( AH_Hinter     hinter,                        FT_GlyphSlot  slot,                        FT_Size       size,                        FT_UInt       glyph_index,                        FT_Int32      load_flags )  {    FT_Face          face         = slot->face;    FT_Error         error;    FT_Fixed         x_scale      = size->metrics.x_scale;    FT_Fixed         y_scale      = size->metrics.y_scale;    AH_Face_Globals  face_globals = FACE_GLOBALS( face );    FT_Render_Mode   hint_mode    = FT_LOAD_TARGET_MODE( load_flags );    /* first of all, we need to check that we're using the correct face and */    /* global hints to load the glyph                                       */    if ( hinter->face != face || hinter->globals != face_globals )    {      hinter->face = face;      if ( !face_globals )      {        error = ah_hinter_new_face_globals( hinter, face, 0 );        if ( error )          goto Exit;      }      hinter->globals = FACE_GLOBALS( face );      face_globals    = FACE_GLOBALS( face );    }#ifdef FT_CONFIG_CHESTER_BLUE_SCALE   /* try to optimize the y_scale so that the top of non-capital letters    * is aligned on a pixel boundary whenever possible    */    {      AH_Globals  design = &face_globals->design;      FT_Pos      shoot  = design->blue_shoots[AH_BLUE_SMALL_TOP];      /* the value of 'shoot' will be -1000 if the font doesn't have */      /* small latin letters; we simply check the sign here...       */      if ( shoot > 0 )      {        FT_Pos  scaled = FT_MulFix( shoot, y_scale );        FT_Pos  fitted = ( scaled + 32 ) & -64;        if ( scaled != fitted )        {         /* adjust y_scale          */          y_scale = FT_MulDiv( y_scale, fitted, scaled );         /* adust x_scale          */          if ( fitted < scaled )            x_scale -= x_scale / 50;  /* x_scale*0.98 with integers */        }      }    }#endif /* FT_CONFIG_CHESTER_BLUE_SCALE */    /* now, we must check the current character pixel size to see if we */    /* need to rescale the global metrics                               */    if ( face_globals->x_scale != x_scale ||         face_globals->y_scale != y_scale )      ah_hinter_scale_globals( hinter, x_scale, y_scale );    ah_loader_rewind( hinter->loader );    /* reset hinting flags according to load flags and current render target */    hinter->do_horz_hints = FT_BOOL( !(load_flags & FT_LOAD_NO_AUTOHINT) );    hinter->do_vert_hints = FT_BOOL( !(load_flags & FT_LOAD_NO_AUTOHINT) );#ifdef DEBUG_HINTER    hinter->do_horz_hints = !ah_debug_disable_vert;  /* not a bug, the meaning */    hinter->do_vert_hints = !ah_debug_disable_horz;  /* of h/v is inverted!    */#endif    /* we snap the width of vertical stems for the monochrome and         */    /* horizontal LCD rendering targets only.  Corresponds to X snapping. */    hinter->do_horz_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO ||                                        hint_mode == FT_RENDER_MODE_LCD  );    /* we snap the width of horizontal stems for the monochrome and     */    /* vertical LCD rendering targets only.  Corresponds to Y snapping. */    hinter->do_vert_snapping = FT_BOOL( hint_mode == FT_RENDER_MODE_MONO   ||                                        hint_mode == FT_RENDER_MODE_LCD_V  );    hinter->do_stem_adjust   = FT_BOOL( hint_mode != FT_RENDER_MODE_LIGHT );    load_flags  |= FT_LOAD_NO_SCALE                 | FT_LOAD_IGNORE_TRANSFORM ;    error = ah_hinter_load( hinter, glyph_index, load_flags, 0 );  Exit:    return error;  }  /* retrieve a face's autohint globals for client applications */  FT_LOCAL_DEF( void )  ah_hinter_get_global_hints( AH_Hinter  hinter,                              FT_Face    face,                              void**     global_hints,                              long*      global_len )  {    AH_Globals  globals = 0;    FT_Memory   memory  = hinter->memory;    FT_Error    error;    /* allocate new master globals */    if ( FT_NEW( globals ) )      goto Fail;    /* compute face globals if needed */    if ( !FACE_GLOBALS( face ) )    {      error = ah_hinter_new_face_globals( hinter, face, 0 );      if ( error )        goto Fail;    }    *globals      = FACE_GLOBALS( face )->design;    *global_hints = globals;    *global_len   = sizeof( *globals );    return;  Fail:    FT_FREE( globals );    *global_hints = 0;    *global_len   = 0;  }  FT_LOCAL_DEF( void )  ah_hinter_done_global_hints( AH_Hinter  hinter,                               void*      global_hints )  {    FT_Memory  memory = hinter->memory;    FT_FREE( global_hints );  }/* END */

⌨️ 快捷键说明

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