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

📄 ahhint.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************//*                                                                         *//*  ahhint.c                                                               *//*                                                                         *//*    Glyph hinter (body).                                                 *//*                                                                         *//*  Copyright 2000-2001, 2002, 2003 Catharon Productions Inc.              *//*  Author: David Turner                                                   *//*                                                                         *//*  This file is part of the Catharon Typography Project and shall only    *//*  be used, modified, and distributed under the terms of the Catharon     *//*  Open Source License that should come with this file under the name     *//*  `CatharonLicense.txt'.  By continuing to use, modify, or distribute    *//*  this file you indicate that you have read the license and              *//*  understand and accept it fully.                                        *//*                                                                         *//*  Note that this license is compatible with the FreeType license.        *//*                                                                         *//***************************************************************************/#include <ft2build.h>#include "ahhint.h"#include "ahglyph.h"#include "ahangles.h"#include "aherrors.h"#include FT_OUTLINE_H#define FACE_GLOBALS( face )  ( (AH_Face_Globals)(face)->autohint.data )#define AH_USE_IUP#define OPTIM_STEM_SNAP  /*************************************************************************/  /*************************************************************************/  /****                                                                 ****/  /****   Hinting routines                                              ****/  /****                                                                 ****/  /*************************************************************************/  /*************************************************************************/  /* snap a given width in scaled coordinates to one of the */  /* current standard widths                                */  static FT_Pos  ah_snap_width( FT_Pos*  widths,                 FT_Int   count,                 FT_Pos   width )  {    int     n;    FT_Pos  best      = 64 + 32 + 2;    FT_Pos  reference = width;    FT_Pos  scaled;    for ( n = 0; n < count; n++ )    {      FT_Pos  w;      FT_Pos  dist;      w = widths[n];      dist = width - w;      if ( dist < 0 )        dist = -dist;      if ( dist < best )      {        best      = dist;        reference = w;      }    }    scaled = ( reference + 32 ) & -64;    if ( width >= reference )    {      if ( width < scaled + 48 )        width = reference;    }    else    {      if ( width > scaled - 48 )        width = reference;    }    return width;  }  /* compute the snapped width of a given stem */#ifdef FT_CONFIG_CHESTER_SERIF  static FT_Pos  ah_compute_stem_width( AH_Hinter      hinter,                         int            vertical,                         FT_Pos         width,                         AH_Edge_Flags  base_flags,                         AH_Edge_Flags  stem_flags )  {    AH_Globals  globals = &hinter->globals->scaled;    FT_Pos      dist    = width;    FT_Int      sign    = 0;    if ( dist < 0 )    {      dist = -width;      sign = 1;    }    if ( !hinter->do_stem_adjust )    {      /* leave stem widths unchanged */    }    else if ( (  vertical && !hinter->do_vert_snapping ) ||              ( !vertical && !hinter->do_horz_snapping ) )    {      /* smooth hinting process: very lightly quantize the stem width */      /*                                                              */      /* leave the widths of serifs alone */      if ( ( stem_flags & AH_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )        goto Done_Width;      else if ( ( base_flags & AH_EDGE_ROUND ) )      {        if ( dist < 80 )          dist = 64;      }      else if ( dist < 56 )        dist = 56;      {        FT_Pos  delta = dist - globals->stds[vertical];        if ( delta < 0 )          delta = -delta;        if ( delta < 40 )        {          dist = globals->stds[vertical];          if ( dist < 48 )            dist = 48;          goto Done_Width;        }        if ( dist < 3 * 64 )        {          delta  = dist & 63;          dist  &= -64;          if ( delta < 10 )            dist += delta;          else if ( delta < 32 )            dist += 10;          else if ( delta < 54 )            dist += 54;          else            dist += delta;        }        else          dist = ( dist + 32 ) & -64;      }    }    else    {      /* strong hinting process: snap the stem width to integer pixels */      /*                                                               */      if ( vertical )      {        dist = ah_snap_width( globals->heights, globals->num_heights, dist );        /* in the case of vertical hinting, always round */        /* the stem heights to integer pixels            */        if ( dist >= 64 )          dist = ( dist + 16 ) & -64;        else          dist = 64;      }      else      {        dist = ah_snap_width( globals->widths, globals->num_widths, dist );        if ( hinter->flags & AH_HINTER_MONOCHROME )        {          /* monochrome horizontal hinting: snap widths to integer pixels */          /* with a different threshold                                   */          if ( dist < 64 )            dist = 64;          else            dist = ( dist + 32 ) & -64;        }        else        {          /* for horizontal anti-aliased hinting, we adopt a more subtle */          /* approach: we strengthen small stems, round stems whose size */          /* is between 1 and 2 pixels to an integer, otherwise nothing  */          if ( dist < 48 )            dist = ( dist + 64 ) >> 1;          else if ( dist < 128 )            dist = ( dist + 22 ) & -64;          else            /* XXX: round otherwise to prevent color fringes in LCD mode */            dist = ( dist + 32 ) & -64;        }      }    }  Done_Width:    if ( sign )      dist = -dist;    return dist;  }#else /* !FT_CONFIG_CHESTER_SERIF */  static FT_Pos  ah_compute_stem_width( AH_Hinter  hinter,                         int        vertical,                         FT_Pos     width )  {    AH_Globals  globals = &hinter->globals->scaled;    FT_Pos      dist    = width;    FT_Int      sign    = 0;    if ( dist < 0 )    {      dist = -width;      sign = 1;    }    if ( !hinter->do_stem_adjust )    {      /* leave stem widths unchanged */    }    else if ( (  vertical && !hinter->do_vert_snapping ) ||              ( !vertical && !hinter->do_horz_snapping ) )    {      /* smooth hinting process: very lightly quantize the stem width */      /*                                                              */      if ( dist < 64 )        dist = 64;      {        FT_Pos  delta = dist - globals->stds[vertical];        if ( delta < 0 )          delta = -delta;        if ( delta < 40 )        {          dist = globals->stds[vertical];          if ( dist < 48 )            dist = 48;        }        if ( dist < 3 * 64 )        {          delta  = dist & 63;          dist  &= -64;          if ( delta < 10 )            dist += delta;          else if ( delta < 32 )            dist += 10;          else if ( delta < 54 )            dist += 54;          else            dist += delta;        }        else          dist = ( dist + 32 ) & -64;      }    }    else    {      /* strong hinting process: snap the stem width to integer pixels */      /*                                                               */      if ( vertical )      {        dist = ah_snap_width( globals->heights, globals->num_heights, dist );        /* in the case of vertical hinting, always round */        /* the stem heights to integer pixels            */        if ( dist >= 64 )          dist = ( dist + 16 ) & -64;        else          dist = 64;      }      else      {        dist = ah_snap_width( globals->widths, globals->num_widths, dist );        if ( hinter->flags & AH_HINTER_MONOCHROME )        {          /* monochrome horizontal hinting: snap widths to integer pixels */          /* with a different threshold                                   */          if ( dist < 64 )            dist = 64;          else            dist = ( dist + 32 ) & -64;        }        else        {          /* for horizontal anti-aliased hinting, we adopt a more subtle */          /* approach: we strengthen small stems, round stems whose size */          /* is between 1 and 2 pixels to an integer, otherwise nothing  */          if ( dist < 48 )            dist = ( dist + 64 ) >> 1;          else if ( dist < 128 )            dist = ( dist + 22 ) & -64;          else            /* XXX: round otherwise to prevent color fringes in LCD mode */            dist = ( dist + 32 ) & -64;        }      }    }    if ( sign )      dist = -dist;    return dist;  }#endif /* !FT_CONFIG_CHESTER_SERIF */  /* align one stem edge relative to the previous stem edge */  static void  ah_align_linked_edge( AH_Hinter  hinter,                        AH_Edge    base_edge,                        AH_Edge    stem_edge,                        int        vertical )  {    FT_Pos  dist = stem_edge->opos - base_edge->opos;#ifdef FT_CONFIG_CHESTER_SERIF    FT_Pos  fitted_width = ah_compute_stem_width( hinter,                                                  vertical,                                                  dist,                                                  base_edge->flags,                                                  stem_edge->flags );    stem_edge->pos = base_edge->pos + fitted_width;#else    stem_edge->pos = base_edge->pos +                     ah_compute_stem_width( hinter, vertical, dist );#endif  }  static void  ah_align_serif_edge( AH_Hinter  hinter,                       AH_Edge    base,                       AH_Edge    serif,                       int        vertical )  {    FT_Pos  dist;    FT_Pos  sign = 1;    FT_UNUSED( hinter );    FT_UNUSED( vertical );    dist = serif->opos - base->opos;    if ( dist < 0 )    {      dist = -dist;      sign = -1;    }#if 0    /* do not touch serifs widths! */    if ( base->flags & AH_EDGE_DONE )    {      if ( dist >= 64 )        dist = ( dist + 8 ) & -64;      else if ( dist <= 32 && !vertical )        dist = ( dist + 33 ) >> 1;      else        dist = 0;    }#endif    serif->pos = base->pos + sign * dist;  }  /*************************************************************************/  /*************************************************************************/  /*************************************************************************/  /****                                                                 ****/  /****       E D G E   H I N T I N G                                   ****/  /****                                                                 ****/  /*************************************************************************/  /*************************************************************************/  /*************************************************************************/  FT_LOCAL_DEF( void )  ah_hinter_hint_edges( AH_Hinter  hinter )  {    AH_Edge     edges;    AH_Edge     edge_limit;    AH_Outline  outline = hinter->glyph;    FT_Int      dimension;    FT_Int      n_edges;    edges      = outline->horz_edges;    edge_limit = edges + outline->num_hedges;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Edge  edge;      AH_Edge  anchor = 0;      int      has_serifs = 0;      if ( !hinter->do_horz_hints && !dimension )        goto Next_Dimension;      if ( !hinter->do_vert_hints && dimension )        goto Next_Dimension;      /* we begin by aligning all stems relative to the blue zone */      /* if needed -- that's only for horizontal edges            */      if ( dimension )      {        for ( edge = edges; edge < edge_limit; edge++ )        {          FT_Pos*      blue;          AH_EdgeRec  *edge1, *edge2;          if ( edge->flags & AH_EDGE_DONE )            continue;          blue  = edge->blue_edge;          edge1 = 0;          edge2 = edge->link;          if ( blue )          {            edge1 = edge;          }          else if ( edge2 && edge2->blue_edge )          {            blue  = edge2->blue_edge;            edge1 = edge2;            edge2 = edge;          }          if ( !edge1 )            continue;

⌨️ 快捷键说明

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