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

📄 ahglyph.c

📁 下载来的一个看图软件的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/***************************************************************************//*                                                                         *//*  ahglyph.c                                                              *//*                                                                         *//*    Routines used to load and analyze a given glyph before hinting       *//*    (body).                                                              *//*                                                                         *//*  Copyright 2000-2001, 2002, 2003 Catharon Productions Inc.              *//*  Author: David Turner                                                   *//*                                                                         *//*  This file is part of the Catharon Typography Project and shall only    *//*  be used, modified, and distributed under the terms of the Catharon     *//*  Open Source License that should come with this file under the name     *//*  `CatharonLicense.txt'.  By continuing to use, modify, or distribute    *//*  this file you indicate that you have read the license and              *//*  understand and accept it fully.                                        *//*                                                                         *//*  Note that this license is compatible with the FreeType license.        *//*                                                                         *//***************************************************************************/#include <ft2build.h>#include "ahglyph.h"#include "ahangles.h"#include "ahglobal.h"#include "aherrors.h"#ifdef AH_DEBUG#include <stdio.h>  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;    }  }  /* A function used to dump the array of linked segments */  void  ah_dump_segments( AH_Outline  outline )  {    AH_Segment  segments;    AH_Segment  segment_limit;    AH_Point    points;    FT_Int      dimension;    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 */  /* compute the direction value of a given vector */  static AH_Direction  ah_compute_direction( FT_Pos  dx,                        FT_Pos  dy )  {    AH_Direction  dir;    FT_Pos        ax = ABS( dx );    FT_Pos        ay = ABS( dy );    dir = AH_DIR_NONE;    /* atan(1/12) == 4.7 degrees */    /* test for vertical direction */    if ( ax * 12 < ay )    {      dir = dy > 0 ? AH_DIR_UP : AH_DIR_DOWN;    }    /* test for horizontal direction */    else if ( ay * 12 < ax )    {      dir = dx > 0 ? AH_DIR_RIGHT : AH_DIR_LEFT;    }    return dir;  }  /* this function is used by ah_get_orientation (see below) to test */  /* the fill direction of given bbox extremum                       */  static FT_Int  ah_test_extremum( FT_Outline*  outline,                    FT_Int       n )  {    FT_Vector  *prev, *cur, *next;    FT_Pos      product;    FT_Int      first, last, c;    FT_Int      retval;    /* we need to compute the `previous' and `next' point */    /* for this extremum; we check whether the extremum   */    /* is start or end of a contour and providing         */    /* appropriate values if so                           */    cur  = outline->points + n;    prev = cur - 1;    next = cur + 1;    first = 0;    for ( c = 0; c < outline->n_contours; c++ )    {      last = outline->contours[c];      if ( n == first )        prev = outline->points + last;      if ( n == last )        next = outline->points + first;      first = last + 1;    }    /* compute the vectorial product -- since we know that the angle */    /* is <= 180 degrees (otherwise it wouldn't be an extremum) we   */    /* can determine the filling orientation if the product is       */    /* either positive or negative                                   */    product = FT_MulDiv( cur->x  - prev->x,  /* in.x  */                         next->y - cur->y,   /* out.y */                         0x40 )              -              FT_MulDiv( cur->y  - prev->y,  /* in.y  */                         next->x - cur->x,   /* out.x */                         0x40 );    retval = 0;    if ( product )      retval = product > 0 ? 2 : 1;    return retval;  }  /* Compute the orientation of path filling.  It differs between TrueType */  /* and Type1 formats.  We could use the `FT_OUTLINE_REVERSE_FILL' flag,  */  /* but it is better to re-compute it directly (it seems that this flag   */  /* isn't correctly set for some weird composite glyphs currently).       */  /*                                                                       */  /* We do this by computing bounding box points, and computing their      */  /* curvature.                                                            */  /*                                                                       */  /* The function returns either 1 or 2.                                   */  /*                                                                       */  static FT_Int  ah_get_orientation( FT_Outline*  outline )  {    FT_BBox  box;    FT_Int   indices_xMin, indices_yMin, indices_xMax, indices_yMax;    FT_Int   n, last;    indices_xMin = -1;    indices_yMin = -1;    indices_xMax = -1;    indices_yMax = -1;    box.xMin = box.yMin =  32767L;    box.xMax = box.yMax = -32768L;    /* is it empty? */    if ( outline->n_contours < 1 )      return 1;    last = outline->contours[outline->n_contours - 1];    for ( n = 0; n <= last; n++ )    {      FT_Pos  x, y;      x = outline->points[n].x;      if ( x < box.xMin )      {        box.xMin     = x;        indices_xMin = n;      }      if ( x > box.xMax )      {        box.xMax     = x;        indices_xMax = n;      }      y = outline->points[n].y;      if ( y < box.yMin )      {        box.yMin     = y;        indices_yMin = n;      }      if ( y > box.yMax )      {        box.yMax     = y;        indices_yMax = n;      }    }    /* test orientation of the extrema */    n = ah_test_extremum( outline, indices_xMin );    if ( n )      goto Exit;    n = ah_test_extremum( outline, indices_yMin );    if ( n )      goto Exit;    n = ah_test_extremum( outline, indices_xMax );    if ( n )      goto Exit;    n = ah_test_extremum( outline, indices_yMax );    if ( !n )      n = 1;  Exit:    return n;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_new                                                     */  /*                                                                       */  /* <Description>                                                         */  /*    Creates a new and empty AH_OutlineRec object.                      */  /*                                                                       */  FT_LOCAL_DEF( FT_Error )  ah_outline_new( FT_Memory    memory,                  AH_Outline*  aoutline )  {    FT_Error    error;    AH_Outline  outline;    if ( !FT_NEW( outline ) )    {      outline->memory = memory;      *aoutline       = outline;    }    return error;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_done                                                    */  /*                                                                       */  /* <Description>                                                         */  /*    Destroys a given AH_OutlineRec object.                             */  /*                                                                       */  FT_LOCAL_DEF( void )  ah_outline_done( AH_Outline  outline )  {    FT_Memory memory = outline->memory;    FT_FREE( outline->horz_edges );    FT_FREE( outline->horz_segments );    FT_FREE( outline->contours );    FT_FREE( outline->points );    FT_FREE( outline );  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_save                                                    */  /*                                                                       */  /* <Description>                                                         */  /*    Saves the contents of a given AH_OutlineRec object into a face's   */  /*    glyph slot.                                                        */  /*                                                                       */  FT_LOCAL_DEF( void )  ah_outline_save( AH_Outline  outline,                   AH_Loader   gloader )  {    AH_Point    point       = outline->points;    AH_Point    point_limit = point + outline->num_points;    FT_Vector*  vec         = gloader->current.outline.points;    char*       tag         = gloader->current.outline.tags;    /* we assume that the glyph loader has already been checked for storage */    for ( ; point < point_limit; point++, vec++, tag++ )    {      vec->x = point->x;      vec->y = point->y;      if ( point->flags & AH_FLAG_CONIC )        tag[0] = FT_CURVE_TAG_CONIC;      else if ( point->flags & AH_FLAG_CUBIC )        tag[0] = FT_CURVE_TAG_CUBIC;      else        tag[0] = FT_CURVE_TAG_ON;    }  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    ah_outline_load                                                    */  /*                                                                       */  /* <Description>                                                         */  /*    Loads an unscaled outline from a glyph slot into an AH_OutlineRec  */  /*    object.                                                            */  /*                                                                       */  FT_LOCAL_DEF( FT_Error )  ah_outline_load( AH_Outline  outline,                   FT_Fixed    x_scale,                   FT_Fixed    y_scale,                   FT_Face     face )  {    FT_Memory    memory       = outline->memory;    FT_Error     error        = AH_Err_Ok;    FT_Outline*  source       = &face->glyph->outline;    FT_Int       num_points   = source->n_points;    FT_Int       num_contours = source->n_contours;    AH_Point     points;    /* check arguments */    if ( !face                                          ||         !face->size                                    ||         face->glyph->format != FT_GLYPH_FORMAT_OUTLINE )      return AH_Err_Invalid_Argument;    /* first of all, reallocate the contours array if necessary */    if ( num_contours > outline->max_contours )    {      FT_Int  new_contours = ( num_contours + 3 ) & -4;      if ( FT_RENEW_ARRAY( outline->contours,                           outline->max_contours,

⌨️ 快捷键说明

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