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

📄 ahglyph.c

📁 qt-embedded-2.3.8.tar.gz源码
💻 C
📖 第 1 页 / 共 3 页
字号:
    points        = outline->points;    segments      = outline->horz_segments;    segment_limit = segments + outline->num_hsegments;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Segment*  seg;      printf ( "Table of %s segments:\n",               !dimension ? "vertical" : "horizontal" );      printf ( "  [ index |  pos |  dir  | link | serif |"               " numl | first | start ]\n" );      for ( seg = segments; seg < segment_limit; seg++ )      {        printf ( "  [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",                 seg - segments,                 (int)seg->pos,                 seg->dir == ah_dir_up                   ? "up"                   : ( seg->dir == ah_dir_down                         ? "down"                         : ( seg->dir == ah_dir_left                               ? "left"                               : ( seg->dir == ah_dir_right                                     ? "right"                                     : "none" ) ) ),                 seg->link ? (seg->link-segments) : -1,                 seg->serif ? (seg->serif-segments) : -1,                 (int)seg->num_linked,                 seg->first - points,                 seg->last - points );      }      segments      = outline->vert_segments;      segment_limit = segments + outline->num_vsegments;    }  }#endif /* AH_DEBUG_GLYPH */  static  void  ah_outline_compute_edges( AH_Outline*  outline )  {    AH_Edge*      edges;    AH_Segment*   segments;    AH_Segment*   segment_limit;    AH_Direction  up_dir;    FT_Int*       p_num_edges;    FT_Int        dimension;    FT_Fixed      scale;    FT_Pos        edge_distance_threshold;    edges         = outline->horz_edges;    segments      = outline->horz_segments;    segment_limit = segments + outline->num_hsegments;    p_num_edges   = &outline->num_hedges;    up_dir        = ah_dir_right;    scale         = outline->y_scale;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Edge*     edge;      AH_Edge*     edge_limit;  /* really == edge + num_edges */      AH_Segment*  seg;      /*********************************************************************/      /*                                                                   */      /* We will begin by generating a sorted table of edges for the       */      /* current direction.  To do so, we simply scan each segment and try */      /* to find an edge in our table that corresponds to its position.    */      /*                                                                   */      /* If no edge is found, we create and insert a new edge in the       */      /* sorted table.  Otherwise, we simply add the segment to the edge's */      /* list which will be processed in the second step to compute the    */      /* edge's properties.                                                */      /*                                                                   */      /* Note that the edges table is sorted along the segment/edge        */      /* position.                                                         */      /*                                                                   */      /*********************************************************************/      edge_distance_threshold = FT_MulFix( outline->edge_distance_threshold,                                           scale );      if ( edge_distance_threshold > 64 / 4 )        edge_distance_threshold = 64 / 4;      edge_limit = edges;      for ( seg = segments; seg < segment_limit; seg++ )      {        AH_Edge*  found = 0;        /* look for an edge corresponding to the segment */        for ( edge = edges; edge < edge_limit; edge++ )        {          FT_Pos  dist;          dist = seg->pos - edge->fpos;          if ( dist < 0 )            dist = -dist;          dist = FT_MulFix( dist, scale );          if ( dist < edge_distance_threshold )          {            found = edge;            break;          }        }        if ( !found )        {          /* insert a new edge in the list and */          /* sort according to the position    */          while ( edge > edges && edge[-1].fpos > seg->pos )          {            edge[0] = edge[-1];            edge--;          }          edge_limit++;          /* clear all edge fields */          memset( edge, 0, sizeof ( *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;        }      }      *p_num_edges = 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, straigth 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                       */      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++ )      {        int  is_round    = 0;  /* does it contain round segments?    */        int  is_straight = 0;  /* does it contain straight segments? */        int  ups         = 0;  /* number of upwards segments         */        int  downs       = 0;  /* number of downwards segments       */        seg = edge->first;        do        {          FT_Bool  is_serif;          /* check for roundness of segment */          if ( seg->flags & ah_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 = seg->serif && seg->serif->edge != edge;          if ( seg->link || is_serif )          {            AH_Edge*     edge2;            AH_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;            else              edge->link  = edge2;          }          seg = seg->edge_next;        } while ( seg != edge->first );        /* set the round/straight flags */        edge->flags = ah_edge_normal;        if ( is_straight == 0 && is_round )          edge->flags |= ah_edge_round;        /* set the edge's main direction */        edge->dir = ah_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;      }      edges         = outline->vert_edges;      segments      = outline->vert_segments;      segment_limit = segments + outline->num_vsegments;      p_num_edges   = &outline->num_vedges;      up_dir        = ah_dir_up;      scale         = outline->x_scale;    }  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_detect_features                                         */  /*                                                                       */  /* <Description>                                                         */  /*    Performs feature detection on a given AH_Outline object.           */  /*                                                                       */  FT_LOCAL_DEF  void  ah_outline_detect_features( AH_Outline*  outline )  {    ah_outline_compute_segments( outline );    ah_outline_link_segments   ( outline );    ah_outline_compute_edges   ( outline );  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_compute_blue_edges                                      */  /*                                                                       */  /* <Description>                                                         */  /*    Computes the `blue edges' in a given outline (i.e. those that must */  /*    be snapped to a blue zone edge (top or bottom).                    */  /*                                                                       */  FT_LOCAL_DEF  void  ah_outline_compute_blue_edges( AH_Outline*       outline,                                       AH_Face_Globals*  face_globals )  {    AH_Edge*     edge       = outline->horz_edges;    AH_Edge*     edge_limit = edge + outline->num_hedges;    AH_Globals*  globals    = &face_globals->design;    FT_Fixed     y_scale    = outline->y_scale;    /* compute for each horizontal edge, which blue zone is closer */    for ( ; edge < edge_limit; edge++ )    {      AH_Blue  blue;      FT_Pos*  best_blue = 0;      FT_Pos   best_dist;  /* initial threshold */      /* compute the initial threshold as a fraction of the EM size */      best_dist = FT_MulFix( face_globals->face->units_per_EM / 40, y_scale );      if ( best_dist > 64 / 4 )        best_dist = 64 / 4;      for ( blue = ah_blue_capital_top; blue < ah_blue_max; blue++ )      {        /* 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 XXX                              */        FT_Bool  is_top_blue  = AH_IS_TOP_BLUE( blue );        FT_Bool  is_major_dir = edge->dir == outline->horz_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;          FT_Pos*  blue_pos = globals->blue_refs + blue;          /* first of all, compare it to the reference position */          dist = edge->fpos - *blue_pos;          if ( dist < 0 )            dist = -dist;          dist = FT_MulFix( dist, y_scale );          if ( dist < best_dist )          {            best_dist = dist;            best_blue = blue_pos;          }          /* 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 & ah_edge_round && dist != 0 )          {            FT_Bool  is_under_ref = edge->fpos < *blue_pos;            if ( is_top_blue ^ is_under_ref )            {              blue_pos = globals->blue_shoots + blue;              dist = edge->fpos - *blue_pos;              if ( dist < 0 )                dist = -dist;              dist = FT_MulFix( dist, y_scale );              if ( dist < best_dist )              {                best_dist = dist;                best_blue = blue_pos;              }            }          }        }      }      if ( best_blue )        edge->blue_edge = best_blue;    }  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_scale_blue_edges                                        */  /*                                                                       */  /* <Description>                                                         */  /*    This functions must be called before hinting in order to re-adjust */  /*    the contents of the detected edges (basically change the `blue     */  /*    edge' pointer from `design units' to `scaled ones').               */  /*                                                                       */  FT_LOCAL_DEF  void  ah_outline_scale_blue_edges( AH_Outline*       outline,                                     AH_Face_Globals*  globals )  {    AH_Edge*  edge       = outline->horz_edges;    AH_Edge*  edge_limit = edge + outline->num_hedges;    FT_Int    delta;    delta = globals->scaled.blue_refs - globals->design.blue_refs;    for ( ; edge < edge_limit; edge++ )    {      if ( edge->blue_edge )        edge->blue_edge += delta;    }  }#ifdef AH_DEBUG_GLYPH  void  ah_dump_edges( AH_Outline*  outline )  {    AH_Edge*     edges;    AH_Edge*     edge_limit;    AH_Segment*  segments;    FT_Int       dimension;    edges      = outline->horz_edges;    edge_limit = edges + outline->num_hedges;    segments   = outline->horz_segments;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AH_Edge*  edge;      printf ( "Table of %s edges:\n",               !dimension ? "vertical" : "horizontal" );      printf ( "  [ index |  pos |  dir  | link |"               " serif | blue | opos  |  pos  ]\n" );      for ( edge = edges; edge < edge_limit; edge++ )      {        printf ( "  [ %5d | %4d | %5s | %4d | %5d |  %c  | %5.2f | %5.2f ]\n",                 edge - edges,                 (int)edge->fpos,                 edge->dir == ah_dir_up                   ? "up"                   : ( edge->dir == ah_dir_down                         ? "down"                         : ( edge->dir == ah_dir_left                               ? "left"                               : ( edge->dir == ah_dir_right                                     ? "right"                                     : "none" ) ) ),                 edge->link ? ( edge->link - edges ) : -1,                 edge->serif ? ( edge->serif - edges ) : -1,                 edge->blue_edge ? 'y' : 'n',                 edge->opos / 64.0,                 edge->pos / 64.0 );      }      edges      = outline->vert_edges;      edge_limit = edges + outline->num_vedges;      segments   = outline->vert_segments;    }  }#endif /* AH_DEBUG_GLYPH *//* END */

⌨️ 快捷键说明

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