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

📄 aflatin.c

📁 qt专门用于嵌入式的图形开发GUI
💻 C
📖 第 1 页 / 共 4 页
字号:
        {          edge[0] = edge[-1];          edge--;        }        edge_limit++;        /* clear all edge fields */        FT_ZERO( edge );        /* add the segment to the new edge's list */        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        = edge->first;        edge->last->edge_next = seg;        edge->last            = seg;      }    }    axis->num_edges = (FT_Int)( edge_limit - edges );    /*********************************************************************/    /*                                                                   */    /* 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 I've tried to remove this loop, setting     * the "edge" field of each segment directly in the     * code above.  For some reason, it slows down execution     * speed -- on a Sun.     */    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 = up_dir;      else if ( ups < downs )        edge->dir = -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;    }  }  FT_LOCAL_DEF( void )  af_latin_hints_detect_features( AF_GlyphHints  hints,                                  AF_Dimension   dim )  {    af_latin_hints_compute_segments( hints, dim );    af_latin_hints_link_segments   ( hints, dim );    af_latin_hints_compute_edges   ( hints, dim );  }  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  = (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;   /* XXX    */    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 + -