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

📄 aflatin.c

📁 qt-x11-opensource-src-4.1.4.tar.gz源码
💻 C
📖 第 1 页 / 共 4 页
字号:
        }      }      if ( !found )      {        AF_Edge   edge;        /* insert a new edge in the list and */        /* sort according to the position    */        error = af_axis_hints_new_edge( axis, seg->pos, memory, &edge );        if ( error )          goto Exit;        /* add the segment to the new edge's list */        FT_ZERO( edge );        edge->first    = seg;        edge->last     = seg;        edge->fpos     = seg->pos;        edge->opos     = edge->pos = FT_MulFix( seg->pos, scale );        seg->edge_next = seg;      }      else      {        /* if an edge was found, simply add the segment to the edge's */        /* list                                                       */        seg->edge_next         = found->first;        found->last->edge_next = seg;        found->last            = seg;      }    }    /*********************************************************************/    /*                                                                   */    /* Good, we will now compute each edge's properties according to     */    /* segments found on its position.  Basically, these are:            */    /*                                                                   */    /*  - edge's main direction                                          */    /*  - stem edge, serif edge or both (which defaults to stem then)    */    /*  - rounded edge, straight or both (which defaults to straight)    */    /*  - link for edge                                                  */    /*                                                                   */    /*********************************************************************/    /* first of all, set the `edge' field in each segment -- this is */    /* required in order to compute edge links                       */    /*     * Note that removing this loop and setting the `edge' field of each     * segment directly in the code above slows down execution speed for     * some reasons on platforms like the Sun.     */    {      AF_Edge  edges      = axis->edges;      AF_Edge  edge_limit = edges + axis->num_edges;      AF_Edge  edge;      for ( edge = edges; edge < edge_limit; edge++ )      {        seg = edge->first;        if ( seg )          do          {            seg->edge = edge;            seg       = seg->edge_next;          } while ( seg != edge->first );      }      /* now, compute each edge properties */      for ( edge = edges; edge < edge_limit; edge++ )      {        FT_Int  is_round    = 0;  /* does it contain round segments?    */        FT_Int  is_straight = 0;  /* does it contain straight segments? */        FT_Pos  ups         = 0;  /* number of upwards segments         */        FT_Pos  downs       = 0;  /* number of downwards segments       */        seg = edge->first;        do        {          FT_Bool  is_serif;          /* check for roundness of segment */          if ( seg->flags & AF_EDGE_ROUND )            is_round++;          else            is_straight++;          /* check for segment direction */          if ( seg->dir == up_dir )            ups   += seg->max_coord-seg->min_coord;          else            downs += seg->max_coord-seg->min_coord;          /* check for links -- if seg->serif is set, then seg->link must */          /* be ignored                                                   */          is_serif = (FT_Bool)( seg->serif && seg->serif->edge != edge );          if ( seg->link || is_serif )          {            AF_Edge     edge2;            AF_Segment  seg2;            edge2 = edge->link;            seg2  = seg->link;            if ( is_serif )            {              seg2  = seg->serif;              edge2 = edge->serif;            }            if ( edge2 )            {              FT_Pos  edge_delta;              FT_Pos  seg_delta;              edge_delta = edge->fpos - edge2->fpos;              if ( edge_delta < 0 )                edge_delta = -edge_delta;              seg_delta = seg->pos - seg2->pos;              if ( seg_delta < 0 )                seg_delta = -seg_delta;              if ( seg_delta < edge_delta )                edge2 = seg2->edge;            }            else              edge2 = seg2->edge;            if ( is_serif )            {              edge->serif   = edge2;              edge2->flags |= AF_EDGE_SERIF;            }            else              edge->link  = edge2;          }          seg = seg->edge_next;        } while ( seg != edge->first );        /* set the round/straight flags */        edge->flags = AF_EDGE_NORMAL;        if ( is_round > 0 && is_round >= is_straight )          edge->flags |= AF_EDGE_ROUND;        /* set the edge's main direction */        edge->dir = AF_DIR_NONE;        if ( ups > downs )          edge->dir = (FT_Char)up_dir;        else if ( ups < downs )          edge->dir = (FT_Char)-up_dir;        else if ( ups == downs )          edge->dir = 0;  /* both up and down! */        /* gets rid of serifs if link is set                */        /* XXX: This gets rid of many unpleasant artefacts! */        /*      Example: the `c' in cour.pfa at size 13     */        if ( edge->serif && edge->link )          edge->serif = 0;      }    }  Exit:    return error;  }  FT_LOCAL_DEF( FT_Error )  af_latin_hints_detect_features( AF_GlyphHints  hints,                                  AF_Dimension   dim )  {    FT_Error  error;    error = af_latin_hints_compute_segments( hints, dim );    if ( !error )    {      af_latin_hints_link_segments( hints, dim );      error = af_latin_hints_compute_edges( hints, dim );    }    return error;  }  FT_LOCAL_DEF( void )  af_latin_hints_compute_blue_edges( AF_GlyphHints    hints,                                     AF_LatinMetrics  metrics )  {    AF_AxisHints  axis       = &hints->axis[ AF_DIMENSION_VERT ];    AF_Edge       edge       = axis->edges;    AF_Edge       edge_limit = edge + axis->num_edges;    AF_LatinAxis  latin      = &metrics->axis[ AF_DIMENSION_VERT ];    FT_Fixed      scale      = latin->scale;    /* compute which blue zones are active, i.e. have their scaled */    /* size < 3/4 pixels                                           */    /* for each horizontal edge search the blue zone which is closest */    for ( ; edge < edge_limit; edge++ )    {      FT_Int    bb;      AF_Width  best_blue = NULL;      FT_Pos    best_dist;  /* initial threshold */      /* compute the initial threshold as a fraction of the EM size */      best_dist = FT_MulFix( metrics->units_per_em / 40, scale );      if ( best_dist > 64 / 2 )        best_dist = 64 / 2;      for ( bb = 0; bb < AF_LATIN_BLUE_MAX; bb++ )      {        AF_LatinBlue  blue = latin->blues + bb;        FT_Bool       is_top_blue, is_major_dir;        /* skip inactive blue zones (i.e., those that are too small) */        if ( !( blue->flags & AF_LATIN_BLUE_ACTIVE ) )          continue;        /* if it is a top zone, check for right edges -- if it is a bottom */        /* zone, check for left edges                                      */        /*                                                                 */        /* of course, that's for TrueType                                  */        is_top_blue  = (FT_Byte)( ( blue->flags & AF_LATIN_BLUE_TOP ) != 0 );        is_major_dir = FT_BOOL( edge->dir == axis->major_dir );        /* if it is a top zone, the edge must be against the major    */        /* direction; if it is a bottom zone, it must be in the major */        /* direction                                                  */        if ( is_top_blue ^ is_major_dir )        {          FT_Pos  dist;          /* first of all, compare it to the reference position */          dist = edge->fpos - blue->ref.org;          if ( dist < 0 )            dist = -dist;          dist = FT_MulFix( dist, scale );          if ( dist < best_dist )          {            best_dist = dist;            best_blue = & blue->ref;          }          /* now, compare it to the overshoot position if the edge is     */          /* rounded, and if the edge is over the reference position of a */          /* top zone, or under the reference position of a bottom zone   */          if ( edge->flags & AF_EDGE_ROUND && dist != 0 )          {            FT_Bool  is_under_ref = FT_BOOL( edge->fpos < blue->ref.org );            if ( is_top_blue ^ is_under_ref )            {              blue = latin->blues + bb;              dist = edge->fpos - blue->shoot.org;              if ( dist < 0 )                dist = -dist;              dist = FT_MulFix( dist, scale );              if ( dist < best_dist )              {                best_dist = dist;                best_blue = & blue->shoot;              }            }          }        }      }      if ( best_blue )        edge->blue_edge = best_blue;    }  }  static FT_Error  af_latin_hints_init( AF_GlyphHints    hints,                       AF_LatinMetrics  metrics )  {    FT_Render_Mode  mode;    af_glyph_hints_rescale( hints, (AF_ScriptMetrics)metrics );    /*     *  correct x_scale and y_scale when needed, since they may have     *  been modified af_latin_scale_dim above     */    hints->x_scale = metrics->axis[AF_DIMENSION_HORZ].scale;    hints->x_delta = metrics->axis[AF_DIMENSION_HORZ].delta;    hints->y_scale = metrics->axis[AF_DIMENSION_VERT].scale;    hints->y_delta = metrics->axis[AF_DIMENSION_VERT].delta;    /* compute flags depending on render mode, etc... */    mode = metrics->root.scaler.render_mode;    /*     *  We snap the width of vertical stems for the monochrome and     *  horizontal LCD rendering targets only.     */    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD )      hints->other_flags |= AF_LATIN_HINTS_HORZ_SNAP;    /*     *  We snap the width of horizontal stems for the monochrome and     *  vertical LCD rendering targets only.     */    if ( mode == FT_RENDER_MODE_MONO || mode == FT_RENDER_MODE_LCD_V )      hints->other_flags |= AF_LATIN_HINTS_VERT_SNAP;    /*     *  We adjust stems to full pixels only if we don't use the `light' mode.     */    if ( mode != FT_RENDER_MODE_LIGHT )      hints->other_flags |= AF_LATIN_HINTS_STEM_ADJUST;    if ( mode == FT_RENDER_MODE_MONO )      hints->other_flags |= AF_LATIN_HINTS_MONO;    return 0;  }  /*************************************************************************/  /*************************************************************************/  /*****                                                               *****/  /*****        L A T I N   G L Y P H   G R I D - F I T T I N G        *****/  /*****                                                               *****/  /*************************************************************************/  /*************************************************************************/  /* snap a given width in scaled coordinates to one of the */  /* current standard widths                                */  static FT_Pos  af_latin_snap_width( AF_Width  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].cur;      dist = width - w;      if ( dist < 0 )        dist = -dist;      if ( dist < best )      {        best      = dist;        reference = w;      }    }    scaled = FT_PIX_ROUND( reference );    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 */  static FT_Pos  af_latin_compute_stem_width( AF_GlyphHints  hints,                               AF_Dimension   dim,                               FT_Pos         width,                               AF_Edge_Flags  base_flags,                               AF_Edge_Flags  stem_flags )  {    AF_LatinMetrics  metrics  = (AF_LatinMetrics) hints->metrics;    AF_LatinAxis     axis     = & metrics->axis[dim];    FT_Pos           dist     = width;    FT_Int           sign     = 0;    FT_Int           vertical = AF_HINTS_DO_VERTICAL( hints );    if ( !AF_LATIN_HINTS_DO_STEM_ADJUST( hints ) )      return width;    if ( dist < 0 )    {      dist = -width;      sign = 1;    }    if ( (  vertical && !AF_LATIN_HINTS_DO_VERT_SNAP( hints ) ) ||         ( !vertical && !AF_LATIN_HINTS_DO_HORZ_SNAP( hints ) ) )    {      /* smooth hinting process: very lightly quantize the stem width */      /* leave the widths of serifs alone */      if ( ( stem_flags & AF_EDGE_SERIF ) && vertical && ( dist < 3 * 64 ) )        goto Done_Width;      else if ( ( base_flags & AF_EDGE_ROUND ) )      {        if ( dist < 80 )          dist = 64;      }      else if ( dist < 56 )        dist = 56;      if ( axis->width_count > 0 )      {        FT_Pos  delta;        /* compare to standard width */        if ( axis->width_count > 0 )        {          delta = dist - axis->widths[0].cur;          if ( delta < 0 )            delta = -delta;          if ( delta < 40 )          {            dist = axis->widths[0].cur;            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 ) & ~63;      }    }    else    {      /* strong hinting process: snap the stem width to integer pixels */

⌨️ 快捷键说明

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