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

📄 t1hinter.c

📁 Qt/Embedded是一个多平台的C++图形用户界面应用程序框架
💻 C
📖 第 1 页 / 共 3 页
字号:
/******************************************************************* * *  t1hinter.c                                                 1.2 * *    Type1 hinter.          * *  Copyright 1996-1999 by *  David Turner, Robert Wilhelm, and Werner Lemberg. * *  This file is part of the FreeType project, and may only be used *  modified and distributed under the terms of the FreeType project *  license, LICENSE.TXT.  By continuing to use, modify, or distribute *  this file you indicate that you have read the license and *  understand and accept it fully. * * *  The Hinter is in charge of fitting th scaled outline to the *  pixel grid in order to considerably improve the quality of *  the Type 1 font driver's output.. * ******************************************************************/#include <ftdebug.h>#include <t1objs.h>#include <t1hinter.h>#undef  FT_COMPONENT#define FT_COMPONENT  trace_t1hint    /* for debugging/tracing */#undef  ONE_PIXEL#define ONE_PIXEL  64#undef  ROUND#define ROUND(x)   (( x + ONE_PIXEL/2 ) & -ONE_PIXEL)#undef  SCALE#define SCALE(val)   FT_MulFix( val, scale )/* various constants used to describe the alignment of a horizontal *//* stem with regards to the blue zones                              */#define T1_ALIGN_NONE    0#define T1_ALIGN_BOTTOM  1#define T1_ALIGN_TOP     2#define T1_ALIGN_BOTH    3/************************************************************************ * * <Function> *    t1_set_blue_zones * * <Description> *    Set a size object's blue zones during reset. This will compute *    the "snap" zone corresponding to each blue zone. * * <Input> *    size  :: handle to target size object * * <Return> *    Error code. 0 means success * * <Note> *    This functions does the following : * *      1. It extracts the bottom and top blue zones from the *         face object. * *      2. Each zone is then grown by  BlueFuzz, overlapping  *         is eliminated by adjusting the zone edges appropriately * *      3. For each zone, we keep its original font units position, its *         original scaled position, as well as its grown/adjusted *         edges. * ************************************************************************/      /* ultra simple bubble sort (not a lot of elements, mostly */      /* pre-sorted, no need for quicksort)                      */      static      void  t1_sort_blues( T1_Int*  blues,                           T1_Int   count )      {        T1_Int  i, swap;        T1_Int* cur;            for ( i = 2; i < count; i += 2 )        {          cur = blues + i;          do          {            if ( cur[-1] < cur[0] )              break;                swap = cur[-2]; cur[-2] = cur[0]; cur[0] = swap;            swap = cur[-1]; cur[-1] = cur[1]; cur[1] = swap;            cur -= 2;          }          while ( cur > blues );        }      }  static  T1_Error  t1_set_blue_zones( T1_Size  size )  {    T1_Face          face = (T1_Face)size->root.face;    T1_Font*         priv = &face->type1;    T1_Int           n;    T1_Int           blues[24];    T1_Int           num_bottom;    T1_Int           num_top;    T1_Int           num_blues;    T1_Size_Hints*   hints = size->hints;    T1_Snap_Zone*    zone;    T1_Pos           pix, orus;    T1_Pos           min, max, threshold;    T1_Fixed         scale;    T1_Bool          is_bottom;    /**********************************************************************/    /*                                                                    */    /*  COPY BOTTOM AND TOP BLUE ZONES IN LOCAL ARRAYS                    */    /*                                                                    */    /*                                                                    */    /* First of all, check the sizes of the /BlueValues and /OtherBlues */    /* tables. They all must contain an even number of arguments        */    if ( priv->num_other_blues & 1 ||         priv->num_blues       & 1 )    {      FT_ERROR(( "T1.Copy_Blues : odd number of blue values\n" ));      return T1_Err_Syntax_Error;    }    /* copy the bottom blue zones from /OtherBlues           */    num_top    = 0;    num_bottom = priv->num_other_blues;    for ( n = 0; n < num_bottom; n ++ )      blues[n] = priv->other_blues[n];    /* Add the first blue zone in /BlueValues to the table */    num_top = priv->num_blues - 2;    if ( num_top >= 0 )    {      blues[ num_bottom ] = priv->blue_values[0];      blues[num_bottom+1] = priv->blue_values[1];      num_bottom += 2;    }    /* sort the bottom blue zones */    t1_sort_blues( blues, num_bottom );    hints->num_bottom_zones = num_bottom >> 1;    /* now copy the /BlueValues to the top of the blues array */    if ( num_top > 0 )    {      for ( n = 0; n < num_top; n++ )        blues[ num_bottom+n ] = priv->blue_values[n+2];      /* sort the top blue zones */      t1_sort_blues( blues + num_bottom, num_top );    }    else      num_top = 0;    num_blues             = num_top + num_bottom;    hints->num_blue_zones = ( num_blues ) >> 1;    /**********************************************************************/    /*                                                                    */    /*    BUILD BLUE SNAP ZONES FROM THE LOCAL BLUES ARRAYS               */    /*                                                                    */    /*                                                                    */    scale     = size->root.metrics.y_scale;    zone      = hints->blue_zones;    threshold = ONE_PIXEL/4;   /* 0.25 pixels */    for ( n = 0; n < num_blues; n += 2, zone ++ )    {      is_bottom = ( n < num_bottom ? 1 : 0 );      orus = blues[n+is_bottom];  /* get alignement coordinate */      pix  = SCALE( orus );       /* scale it                  */      min  = SCALE( blues[ n ] - priv->blue_fuzz );      max  = SCALE( blues[n+1] + priv->blue_fuzz );      if ( min > pix - threshold ) min = pix - threshold;      if ( max < pix + threshold ) max = pix + threshold;      zone->orus = orus;      zone->pix  = pix;      zone->min  = min;      zone->max  = max;    }    /* adjust edges in case of overlap */    zone = hints->blue_zones;    for ( n = 0; n < num_blues-2; n += 2, zone ++ )    {      if ( n != num_bottom-2         &&           zone[0].max > zone[1].min )      {        zone[0].max = zone[1].min = (zone[0].pix+zone[1].pix)/2;      }    }        /* Compare the current pixel size with the BlueScale value */    /* to know wether to supress overshoots..                  */        hints->supress_overshoots =       ( size->root.metrics.y_ppem < FT_MulFix(1000,priv->blue_scale) );    /* Now print the new blue values in tracing mode */#ifdef FT_DEBUG_LEVEL_TRACE        FT_TRACE2(( "Blue Zones for size object at $%08lx :\n", (long)size ));    FT_TRACE2(( "   orus    pix    min   max\n" ));    FT_TRACE2(( "-------------------------------\n" ));        zone = hints->blue_zones;    for ( n = 0; n < hints->num_blue_zones; n++ )    {      FT_TRACE2(( "    %3d   %.2f   %.2f  %.2f\n",                zone->orus,                 zone->pix/64.0,                zone->min/64.0,                 zone->max/64.0 ));      zone++;    }    FT_TRACE2(( "\nOver shoots are %s\n\n",              hints->supress_overshoots ? "supressed" : "active" ));#endif /* DEBUG_LEVEL_TRACE */                                   return T1_Err_Ok;  }/************************************************************************ * * <Function> *    t1_set_snap_zones * * <Description> *    This function set a size object's stem snap zones. * * <Input> *    size :: handle to target size object * * <Return> *    Error code. 0 means success * * <Note> *    This function performs the following : * *      1. It reads and scales the stem snap widths from the parent face *      *      2. A "snap zone" is computed for each snap width, by "growing" *         it with a threshold of a 1/2 pixel. Overlapping is avoided *         through proper edge adjustment. * *      3. Each width whose zone contain the scaled standard set width *         is removed from the table * *      4. Finally, the standard set width is scaled, and its correponding *         "snap zone" is inserted into the sorted snap zones table * ************************************************************************/  static  T1_Error  t1_set_snap_zones( T1_Size  size )  {    T1_Int         n, direction, n_zones, num_zones;    T1_Snap_Zone*  zone;    T1_Snap_Zone*  base_zone;    T1_Short*      orgs;    T1_Pos         standard_width;    T1_Fixed       scale;    T1_Face         face = (T1_Face)size->root.face;    T1_Font*        priv = &face->type1;    T1_Size_Hints*  hints = size->hints;    /* start with horizontal snap zones */    direction      = 0;    standard_width = priv->standard_width;    n_zones        = priv->num_snap_widths;    base_zone      = hints->snap_widths;    orgs           = priv->stem_snap_widths;    scale          = size->root.metrics.x_scale;        while (direction < 2)    {      /*****************************************************************/      /*                                                               */      /*  Read and scale stem snap widths table from the physical      */      /*  font record.                                                 */      /*                                                               */      T1_Pos  prev, orus, pix, min, max, threshold;            threshold = ONE_PIXEL/4;      zone      = base_zone;      if ( n_zones > 0 )      {        orus = *orgs++;        pix  = SCALE( orus );        min  = pix-threshold;        max  = pix+threshold;        zone->orus = orus;        zone->pix  = pix;        zone->min  = min;        prev       = pix;        for ( n = 1; n < n_zones; n++ )        {          orus = *orgs++;          pix  = SCALE( orus );          if ( pix-prev < 2*threshold )          {            min = max = (pix+prev)/2;          }          else            min = pix-threshold;          zone->max = max;          zone++;          zone->orus = orus;          zone->pix  = pix;          zone->min  = min;          max  = pix+threshold;          prev = pix;        }        zone->max = max;      }      /* print the scaled stem snap values in tracing modes */#ifdef FT_DEBUG_LEVEL_TRACE            FT_TRACE2(( "Set_Snap_Zones : first %s pass\n",                 direction ? "vertical" : "horizontal" ));                      FT_TRACE2(( "Scaled original stem snap zones :\n" ));      FT_TRACE2(( "   orus   pix   min   max\n" ));      FT_TRACE2(( "-----------------------------\n" ));            zone = base_zone;      for ( n = 0; n < n_zones; n++, zone++ )        FT_TRACE2(( "  %3d  %.2f  %.2f  %.2f\n",                  zone->orus,                  zone->pix/64.0,                  zone->min/64.0,                  zone->max/64.0 ));      FT_TRACE2(( "\n" ));            FT_TRACE2(( "Standard width = %d\n", standard_width ));#endif      /*****************************************************************/      /*                                                               */      /*  Now, each snap width which is in the range of the standard   */      /*  set width will be removed from the list..                    */      /*                                                               */      if ( standard_width > 0 )      {        T1_Snap_Zone*  parent;        T1_Pos         std_pix, std_min, std_max;        std_pix = SCALE( standard_width );                std_min = std_pix-threshold;        std_max = std_pix+threshold;        num_zones = 0;        zone      = base_zone;        parent    = base_zone;        for ( n = 0; n < n_zones; n++ )        {          if ( zone->pix >= std_min && zone->pix <= std_max )          {            /* this zone must be removed from the list */            if ( std_min > zone->min ) std_min = zone->min;            if ( std_max < zone->max ) std_max = zone->max;          }          else          {            *parent++ = *zone;            num_zones++;          }          zone++;        }                /**********************************************/        /*  Now, insert the standard width zone       */                zone = base_zone+num_zones;        while ( zone > base_zone && zone[-1].pix > std_max )        {          zone[0] = zone[-1];          zone --;        }                /* check border zones */        if ( zone > base_zone && zone[-1].max > std_min )          zone[-1].max = std_min;                  if ( zone < base_zone+num_zones && zone[1].min < std_max )          zone[1].min = std_max;                zone->orus = standard_width;        zone->pix  = std_pix;

⌨️ 快捷键说明

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