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

📄 afhints.c

📁 qt专门用于嵌入式的图形开发GUI
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "afhints.h"#ifdef AF_DEBUG#include <stdio.h>  static const char* af_dir_str( AF_Direction  dir )  {    const char*  result;    switch (dir)    {     case AF_DIR_UP:    result = "up";    break;     case AF_DIR_DOWN:  result = "down";  break;     case AF_DIR_LEFT:  result = "left";  break;     case AF_DIR_RIGHT: result = "right"; break;     default:           result = "none";    }    return result;  }#define  AF_INDEX_NUM(ptr,base)  ( (ptr) ? ((ptr)-(base)) : -1 )  void  af_glyph_hints_dump_points( AF_GlyphHints  hints )  {    AF_Point  points = hints->points;    AF_Point  limit  = points + hints->num_points;    AF_Point  point;    printf( "Table of points:\n" );    printf(   "  [ index |  xorg |  yorg |  xscale |  yscale |  xfit  |  yfit  |  flags ]\n" );    for ( point = points; point < limit; point++ )    {      printf( "  [ %5d | %5d | %5d | %-5.2f | %-5.2f | %-5.2f | %-5.2f | %c%c%c%c%c%c ]\n",              point - points,              point->fx,              point->fy,              point->ox/64.0,              point->oy/64.0,              point->x/64.0,              point->y/64.0,              (point->flags & AF_FLAG_WEAK_INTERPOLATION) ? 'w' : ' ',              (point->flags & AF_FLAG_INFLECTION)         ? 'i' : ' ',              (point->flags & AF_FLAG_EXTREMA_X)          ? '<' : ' ',              (point->flags & AF_FLAG_EXTREMA_Y)          ? 'v' : ' ',              (point->flags & AF_FLAG_ROUND_X)            ? '(' : ' ',              (point->flags & AF_FLAG_ROUND_Y)            ? 'u' : ' '            );    }    printf( "\n" );  }  /* A function used to dump the array of linked segments */  void  af_glyph_hints_dump_segments( AF_GlyphHints  hints )  {    AF_Point    points = hints->points;    FT_Int      dimension;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AF_AxisHints  axis = &hints->axis[dimension];      AF_Segment    segments = axis->segments;      AF_Segment    limit    = segments + axis->num_segments;      AF_Segment    seg;      printf ( "Table of %s segments:\n",               dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );      printf ( "  [ index |  pos |  dir  | link | serif |"               " numl | first | start ]\n" );      for ( seg = segments; seg < limit; seg++ )      {        printf ( "  [ %5d | %4d | %5s | %4d | %5d | %4d | %5d | %5d ]\n",                 seg - segments,                 (int)seg->pos,                 af_dir_str( seg->dir ),                 AF_INDEX_NUM( seg->link, segments ),                 AF_INDEX_NUM( seg->serif, segments ),                 (int)seg->num_linked,                 seg->first - points,                 seg->last - points );      }      printf( "\n" );    }  }  void  af_glyph_hints_dump_edges( AF_GlyphHints  hints )  {    FT_Int      dimension;    for ( dimension = 1; dimension >= 0; dimension-- )    {      AF_AxisHints  axis  = &hints->axis[ dimension ];      AF_Edge       edges = axis->edges;      AF_Edge       limit = edges + axis->num_edges;      AF_Edge       edge;     /* note: AF_DIMENSION_HORZ corresponds to _vertical_ edges      * since they have constant X coordinate      */      printf ( "Table of %s edges:\n",               dimension == AF_DIMENSION_HORZ ? "vertical" : "horizontal" );      printf ( "  [ index |  pos |  dir  | link |"               " serif | blue | opos  |  pos  ]\n" );      for ( edge = edges; edge < limit; edge++ )      {        printf ( "  [ %5d | %4d | %5s | %4d | %5d |   %c  | %5.2f | %5.2f ]\n",                 edge - edges,                 (int)edge->fpos,                 af_dir_str( edge->dir ),                 AF_INDEX_NUM( edge->link, edges ),                 AF_INDEX_NUM( edge->serif, edges ),                 edge->blue_edge ? 'y' : 'n',                 edge->opos / 64.0,                 edge->pos / 64.0 );      }      printf( "\n" );    }  }#endif /* AF_DEBUG */  /* compute the direction value of a given vector */  FT_LOCAL_DEF( AF_Direction )  af_direction_compute( FT_Pos  dx,                        FT_Pos  dy )  {    AF_Direction  dir;    FT_Pos        ax = FT_ABS( dx );    FT_Pos        ay = FT_ABS( dy );    dir = AF_DIR_NONE;    /* atan(1/12) == 4.7 degrees */    /* test for vertical direction */    if ( ax * 12 < ay )    {      dir = dy > 0 ? AF_DIR_UP : AF_DIR_DOWN;    }    /* test for horizontal direction */    else if ( ay * 12 < ax )    {      dir = dx > 0 ? AF_DIR_RIGHT : AF_DIR_LEFT;    }    return dir;  }  /* compute all inflex points in a given glyph */  static void  af_glyph_hints_compute_inflections( AF_GlyphHints  hints )  {    AF_Point*  contour       = hints->contours;    AF_Point*  contour_limit = contour + hints->num_contours;    /* do each contour separately */    for ( ; contour < contour_limit; contour++ )    {      AF_Point   point = contour[0];      AF_Point   first = point;      AF_Point   start = point;      AF_Point   end   = point;      AF_Point   before;      AF_Point   after;      AF_Angle   angle_in, angle_seg, angle_out;      AF_Angle   diff_in, diff_out;      FT_Int     finished = 0;      /* compute first segment in contour */      first = point;      start = end = first;      do      {        end = end->next;        if ( end == first )          goto Skip;      } while ( end->fx == first->fx && end->fy == first->fy );      angle_seg = af_angle_atan( end->fx - start->fx,                                 end->fy - start->fy );      /* extend the segment start whenever possible */      before = start;      do      {        do        {          start  = before;          before = before->prev;          if ( before == first )            goto Skip;        } while ( before->fx == start->fx && before->fy == start->fy );        angle_in = af_angle_atan( start->fx - before->fx,                                  start->fy - before->fy );      } while ( angle_in == angle_seg );      first   = start;      diff_in = af_angle_diff( angle_in, angle_seg );      /* now, process all segments in the contour */      do      {        /* first, extend current segment's end whenever possible */        after = end;        do        {          do          {            end   = after;            after = after->next;            if ( after == first )              finished = 1;          } while ( end->fx == after->fx && end->fy == after->fy );          angle_out = af_angle_atan( after->fx - end->fx,                                     after->fy - end->fy );        } while ( angle_out == angle_seg );        diff_out = af_angle_diff( angle_seg, angle_out );        if ( ( diff_in ^ diff_out ) < 0 )        {          /* diff_in and diff_out have different signs, we have */          /* inflection points here...                          */          do          {            start->flags |= AF_FLAG_INFLECTION;            start = start->next;          } while ( start != end );          start->flags |= AF_FLAG_INFLECTION;        }        start     = end;        end       = after;        angle_seg = angle_out;        diff_in   = diff_out;      } while ( !finished );    Skip:      ;    }  }  FT_LOCAL_DEF( void )  af_glyph_hints_init( AF_GlyphHints  hints,                       FT_Memory      memory )  {    FT_ZERO( hints );    hints->memory = memory;  }  FT_LOCAL_DEF( void )  af_glyph_hints_done( AF_GlyphHints  hints )  {    if ( hints && hints->memory )    {      FT_Memory     memory = hints->memory;      AF_Dimension  dim;     /* note that we don't need to free the segment and edge      * buffers, since they're really within the hints->points array      */      for ( dim = 0; dim < 2; dim++ )      {        AF_AxisHints  axis = &hints->axis[ dim ];        axis->num_segments = 0;        axis->num_edges    = 0;        axis->segments     = NULL;        axis->edges        = NULL;      }      FT_FREE( hints->contours );      hints->max_contours = 0;      hints->num_contours = 0;      FT_FREE( hints->points );      hints->num_points = 0;      hints->max_points = 0;      hints->memory = NULL;    }  }  FT_LOCAL_DEF( void )  af_glyph_hints_rescale( AF_GlyphHints     hints,                          AF_ScriptMetrics  metrics )  {    hints->metrics = metrics;  }  FT_LOCAL_DEF( FT_Error )  af_glyph_hints_reload( AF_GlyphHints     hints,                         FT_Outline*       outline )  {    FT_Error     error        = FT_Err_Ok;    AF_Point     points;    FT_UInt      old_max, new_max;    AF_Scaler    scaler  = &hints->metrics->scaler;    FT_Fixed     x_scale = hints->x_scale;    FT_Fixed     y_scale = hints->y_scale;    FT_Pos       x_delta = hints->x_delta;    FT_Pos       y_delta = hints->y_delta;    FT_Memory    memory  = hints->memory;    hints->scaler_flags  = scaler->flags;    hints->num_points    = 0;    hints->num_contours  = 0;    hints->axis[0].num_segments = 0;    hints->axis[0].num_edges    = 0;    hints->axis[1].num_segments = 0;    hints->axis[1].num_edges    = 0;   /* first of all, reallocate the contours array when necessary    */    new_max = (FT_UInt) outline->n_contours;    old_max = hints->max_contours;    if ( new_max > old_max )    {      new_max = (new_max + 3) & ~3;      if ( FT_RENEW_ARRAY( hints->contours, old_max, new_max ) )        goto Exit;      hints->max_contours = new_max;    }   /* then, reallocate the points, segments & edges arrays if needed --    * note that we reserved two additional point positions, used to    * hint metrics appropriately    */    new_max = (FT_UInt)( outline->n_points + 2 );    old_max = hints->max_points;    if ( new_max > old_max )    {      FT_Byte*    items;      FT_ULong    off1, off2, off3;     /* we store in a single buffer the following arrays:      *      *  - an array of   N  AF_PointRec   items      *  - an array of 2*N  AF_SegmentRec items      *  - an array of 2*N  AF_EdgeRec    items      *      */      new_max = ( new_max + 2 + 7 ) & ~7;#define OFF_PAD2(x,y)   (((x)+(y)-1) & ~((y)-1))#define OFF_PADX(x,y)   ((((x)+(y)-1)/(y))*(y))#define OFF_PAD(x,y)    ( ((y) & ((y)-1)) ? OFF_PADX(x,y) : OFF_PAD2(x,y) )#undef  OFF_INCREMENT#define OFF_INCREMENT( _off, _type, _count )   \     ( OFF_PAD( _off, sizeof(_type) ) + (_count)*sizeof(_type))      off1 = OFF_INCREMENT( 0, AF_PointRec, new_max );      off2 = OFF_INCREMENT( off1, AF_SegmentRec, new_max*2 );      off3 = OFF_INCREMENT( off2, AF_EdgeRec, new_max*2 );      FT_FREE( hints->points );      if ( FT_ALLOC( items, off3 ) )      {        hints->max_points       = 0;        hints->axis[0].segments = NULL;        hints->axis[0].edges    = NULL;        hints->axis[1].segments = NULL;        hints->axis[1].edges    = NULL;        goto Exit;      }     /* readjust some pointers      */      hints->max_points       = new_max;      hints->points           = (AF_Point) items;      hints->axis[0].segments = (AF_Segment)( items + off1 );      hints->axis[1].segments = hints->axis[0].segments + new_max;      hints->axis[0].edges    = (AF_Edge)   ( items + off2 );      hints->axis[1].edges    = hints->axis[0].edges + new_max;    }    hints->num_points   = outline->n_points;    hints->num_contours = outline->n_contours;    /* We can't rely on the value of `FT_Outline.flags' to know the fill  */    /* direction used for a glyph, given that some fonts are broken (e.g. */    /* the Arphic ones).  We thus recompute it each time we need to.      */    /*                                                                    */    hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_UP;    hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_LEFT;    if ( FT_Outline_Get_Orientation( outline ) == FT_ORIENTATION_POSTSCRIPT )    {      hints->axis[ AF_DIMENSION_HORZ ].major_dir = AF_DIR_DOWN;      hints->axis[ AF_DIMENSION_VERT ].major_dir = AF_DIR_RIGHT;    }    hints->x_scale = x_scale;    hints->y_scale = y_scale;    hints->x_delta = x_delta;    hints->y_delta = y_delta;    points = hints->points;    if ( hints->num_points == 0 )      goto Exit;    {      AF_Point  point;      AF_Point  point_limit = points + hints->num_points;      /* compute coordinates & bezier flags */      {        FT_Vector*  vec = outline->points;        char*       tag = outline->tags;        for ( point = points; point < point_limit; point++, vec++, tag++ )        {          point->fx = vec->x;          point->fy = vec->y;          point->ox = point->x = FT_MulFix( vec->x, x_scale ) + x_delta;          point->oy = point->y = FT_MulFix( vec->y, y_scale ) + y_delta;          switch ( FT_CURVE_TAG( *tag ) )          {          case FT_CURVE_TAG_CONIC:            point->flags = AF_FLAG_CONIC;            break;          case FT_CURVE_TAG_CUBIC:            point->flags = AF_FLAG_CUBIC;            break;          default:            point->flags = 0;            ;          }        }      }      /* compute `next' and `prev' */      {        FT_Int    contour_index;        AF_Point  prev;        AF_Point  first;        AF_Point  end;        contour_index = 0;        first = points;        end   = points + outline->contours[0];        prev  = end;        for ( point = points; point < point_limit; point++ )        {          point->prev = prev;          if ( point < end )

⌨️ 快捷键说明

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